排序算法 (Sorting Algorithms)-JS示例
基本概念
排序算法是将一组数据按照特定顺序(通常是升序或降序)重新排列的算法。它是计算机科学中最基础也是最重要的算法之一。
核心特性
- 稳定性:相等元素在排序后的相对位置不变
- 时间复杂度:算法执行所需的时间
- 空间复杂度:算法执行所需的额外存储空间
- 原地排序:只需要常数级额外空间的排序算法
常见分类
- 比较排序:通过比较元素大小来决定顺序(如冒泡排序、快速排序)
- 非比较排序:不通过比较元素大小(如计数排序、桶排序)
经典排序算法 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));