基本概念
排序算法是将一组数据按照特定顺序(通常是升序或降序)重新排列的算法。它是计算机科学中最基础也是最重要的算法之一。
核心特性
- 稳定性:相等元素在排序后的相对位置不变
- 时间复杂度:算法执行所需的时间
- 空间复杂度:算法执行所需的额外存储空间
- 原地排序:只需要常数级额外空间的排序算法
常见分类
- 比较排序:通过比较元素大小来决定顺序(如冒泡排序、快速排序)
- 非比较排序:不通过比较元素大小(如计数排序、桶排序)
经典排序算法 JS 示例
1. 冒泡排序 (Bubble Sort)
function bubbleSort(arr) {
const n = arr.length;
// 创建数组副本以避免修改原数组
const result = [...arr];
for (let i = 0; i < n - 1; i++) {
let swapped = false;
// 每轮将最大元素"冒泡"到末尾
for (let j = 0; j < n - i - 1; j++) {
if (result[j] > result[j + 1]) {
// 交换元素
[result[j], result[j + 1]] = [result[j + 1], result[j]];
swapped = true;
}
}
// 如果没有发生交换,说明数组已经有序
if (!swapped) break;
}
return result;
}
// 示例使用
const arr1 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr1);
console.log('冒泡排序结果:', bubbleSort(arr1));
2. 选择排序 (Selection Sort)
function selectionSort(arr) {
const n = arr.length;
const result = [...arr];
for (let i = 0; i < n - 1; i++) {
// 找到未排序部分的最小元素索引
let minIndex = i;
for (let j = i + 1; j < n; j++) {
if (result[j] < result[minIndex]) {
minIndex = j;
}
}
// 将最小元素与未排序部分的第一个元素交换
if (minIndex !== i) {
[result[i], result[minIndex]] = [result[minIndex], result[i]];
}
}
return result;
}
// 示例使用
const arr2 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr2);
console.log('选择排序结果:', selectionSort(arr2));
3. 插入排序 (Insertion Sort)
function insertionSort(arr) {
const result = [...arr];
for (let i = 1; i < result.length; i++) {
const key = result[i];
let j = i - 1;
// 将大于key的元素向右移动
while (j >= 0 && result[j] > key) {
result[j + 1] = result[j];
j--;
}
result[j + 1] = key;
}
return result;
}
// 示例使用
const arr3 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr3);
console.log('插入排序结果:', insertionSort(arr3));
4. 快速排序 (Quick Sort)
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
const pivot = arr[Math.floor(arr.length / 2)];
const left = [];
const right = [];
const equal = [];
for (let element of arr) {
if (element < pivot) {
left.push(element);
} else if (element > pivot) {
right.push(element);
} else {
equal.push(element);
}
}
return [...quickSort(left), ...equal, ...quickSort(right)];
}
// 原地快速排序版本
function quickSortInPlace(arr, low = 0, high = arr.length - 1) {
if (low < high) {
const pi = partition(arr, low, high);
quickSortInPlace(arr, low, pi - 1);
quickSortInPlace(arr, pi + 1, high);
}
return arr;
}
function partition(arr, low, high) {
const pivot = arr[high];
let i = low - 1;
for (let j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
[arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
return i + 1;
}
// 示例使用
const arr4 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr4);
console.log('快速排序结果:', quickSort([...arr4]));
5. 归并排序 (Merge Sort)
function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left, right) {
const result = [];
let leftIndex = 0;
let rightIndex = 0;
// 合并两个已排序的数组
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex]);
leftIndex++;
} else {
result.push(right[rightIndex]);
rightIndex++;
}
}
// 添加剩余元素
return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}
// 示例使用
const arr5 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr5);
console.log('归并排序结果:', mergeSort(arr5));
6. 堆排序 (Heap Sort)
function heapSort(arr) {
const result = [...arr];
const n = result.length;
// 构建最大堆
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
heapify(result, n, i);
}
// 逐个提取元素
for (let i = n - 1; i > 0; i--) {
[result[0], result[i]] = [result[i], result[0]]; // 将当前最大元素移到末尾
heapify(result, i, 0); // 重新调整堆
}
return result;
}
function heapify(arr, n, i) {
let largest = i;
const left = 2 * i + 1;
const right = 2 * i + 2;
if (left < n && arr[left] > arr[largest]) {
largest = left;
}
if (right < n && arr[right] > arr[largest]) {
largest = right;
}
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, n, largest);
}
}
// 示例使用
const arr6 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr6);
console.log('堆排序结果:', heapSort(arr6));