冒泡排序 (Bubble Sort) 时间复杂度: O(n²) - 最坏、平均情况 空间复杂度: O(1) - 原地排序 稳定性: 稳定
工作原理: 重复遍历数组,比较相邻元素并交换位置 每轮遍历将当前最大元素”冒泡”到末尾 下一轮遍历长度减少 1(已排序部分)
@param {Array} arr
- 需要排序的数组 @return {Array} - 排序后的数组(原地修改)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 function bubbleSort (arr ) { const len = arr.length ; for (let i = 0 ; i < len - 1 ; i++) { let swapped = false ; for (let j = 0 ; j < len - 1 - i; j++) { if (arr[j] > arr[j + 1 ]) { [arr[j], arr[j + 1 ]] = [arr[j + 1 ], arr[j]]; swapped = true ; } } if (!swapped) break ; } return arr; }
插入排序 (Insertion Sort) 时间复杂度: O(n²) - 最坏、平均情况; O(n) - 最好情况(已排序) 空间复杂度: O(1) - 原地排序 稳定性: 稳定
工作原理: 将数组分为已排序和未排序两部分 初始时已排序部分只有第一个元素 每次从未排序部分取出一个元素,插入到已排序部分的正确位置 像整理扑克牌一样逐步构建有序数组
@param {Array} arr
- 需要排序的数组 @return {Array} - 排序后的数组(原地修改)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function insertionSort (arr ) { const len = arr.length ; for (let i = 1 ; i < len; i++) { const current = arr[i]; let j = i - 1 ; while (j >= 0 && arr[j] > current) { arr[j + 1 ] = arr[j]; j--; } arr[j + 1 ] = current; } return arr; }
快速排序 (Quick Sort) 时间复杂度: O(n log n) - 平均情况; O(n²) - 最坏情况 空间复杂度: O(log n) - 递归调用栈 稳定性: 不稳定
选择一个”基准”元素(pivot) 将小于基准的元素放左边,大于基准的放右边 递归地对左右两个子数组进行快速排序 分治法的典型应用
@param {Array} arr
- 需要排序的数组 @param {number} [left=0]
- 起始索引 @param {number} [right=arr.length-1]
- 结束索引 @return {Array} - 排序后的数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 function quickSort (arr, left = 0 , right = arr.length - 1 ) { if (left >= right) { return arr; } const pivotIndex = partition (arr, left, right); quickSort (arr, left, pivotIndex - 1 ); quickSort (arr, pivotIndex + 1 , right); return arr; } function partition (arr, left, right ) { const pivot = arr[right]; let i = left - 1 ; for (let j = left; j < right; j++) { if (arr[j] < pivot) { i++; [arr[i], arr[j]] = [arr[j], arr[i]]; } } [arr[i + 1 ], arr[right]] = [arr[right], arr[i + 1 ]]; return i + 1 ; }
归并排序 (Merge Sort) 时间复杂度: O(n log n) - 所有情况 空间复杂度: O(n) - 需要额外空间存储合并结果 稳定性: 稳定
分治法: 将数组分成两半,递归排序 将排序后的两半合并为一个有序数组 不断分割直到子数组长度为 1(天然有序)
@param {Array} arr
- 需要排序的数组 @return {Array} - 排序后的新数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 function mergeSort (arr ) { const len = arr.length ; if (len <= 1 ) { return arr; } const mid = Math .floor (len / 2 ); const left = arr.slice (0 , mid); const right = arr.slice (mid); const sortedLeft = mergeSort (left); const sortedRight = mergeSort (right); return merge (sortedLeft, sortedRight); } 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)); }
计数排序 (Count Sort) - 适用于整数范围较小的场景 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 function countSort (arr ) { if (arr.length <= 1 ) return [...arr]; let max = arr[0 ]; let min = arr[0 ]; for (let i = 1 ; i < arr.length ; i++) { if (arr[i] > max) max = arr[i]; if (arr[i] < min) min = arr[i]; } const range = max - min + 1 ; const counts = new Array (range).fill (0 ); for (let i = 0 ; i < arr.length ; i++) { counts[arr[i] - min]++; } const result = []; for (let i = 0 ; i < range; i++) { while (counts[i] > 0 ) { result.push (i + min); counts[i]--; } } return result; }
排序算法比较表
排序算法
时间复杂度(平均)
时间复杂度(最好)
时间复杂度(最坏)
空间复杂度
稳定性
特点
冒泡排序
O(n²)
O(n)
O(n²)
O(1)
稳定
简单,适合小数据集
插入排序
O(n²)
O(n)
O(n²)
O(1)
稳定
对近乎有序数据高效
快速排序
O(n log n)
O(n log n)
O(n²)
O(log n)
不稳定
实际应用最广泛
归并排序
O(n log n)
O(n log n)
O(n log n)
O(n)
稳定
性能稳定但需额外空间
计数排序
O(n + k)
O(n + k)
O(n + k)
O(k)
稳定
适用于整数范围较小情况
JavaScript 的 sort()方法在不同浏览器中实现方式不同,但大多采用这些算法的混合:
V8 引擎(Chrome/Node.js): 对于小数组(长度<10)使用插入排序,大数组使用快速排序的变种——TimSort(结合了归并排序和插入排序)
SpiderMonkey(Firefox): 使用归并排序
JavaScriptCore(Safari): 使用混合排序算法