JavaScript 中常见排序算法的实现代码

时之世 发布于 8 天前 177 次阅读 预计阅读时间: 4 分钟 最后更新于 8 天前 776 字 无~


一、冒泡排序 (Bubble Sort)

原理​​:相邻元素两两比较交换,每轮将最大值"冒泡"到末尾,可提前终止无交换的遍历
​时间复杂度​​:O(n²)(平均情况)
​稳定性​​:稳定

function bubbleSort(arr) {
  let swapped;
  for (let i = 0; i < arr.length; i++) {
    swapped = false;
    for (let j = 0; j < arr.length - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // 交换元素
        swapped = true;
      }
    }
    if (!swapped) break; // 无交换时提前终止
  }
  return arr;
}

二、快速排序 (Quick Sort)

原理​​:分治法选取基准值,递归划分左右子数组
​时间复杂度​​:O(n log n)(平均情况)
​稳定性​​:不稳定

function quickSort(arr) {
  if (arr.length <= 1) return arr;
  const pivot = arr[Math.floor(arr.length / 2)]; // 基准值
  const left = [], right = [];
  for (const num of arr) {
    if (num < pivot) left.push(num);
    else if (num > pivot) right.push(num);
  }
  return [...quickSort(left), pivot, ...quickSort(right)];
}

三、插入排序 (Insertion Sort)

原理​​:逐个将元素插入已排序序列的正确位置
​时间复杂度​​:O(n²)(平均情况)
​稳定性​​:稳定

function insertionSort(arr) {
  for (let i = 1; i < arr.length; i++) {
    const key = arr[i];
    let j = i - 1;
    while (j >= 0 && arr[j] > key) {
      arr[j + 1] = arr[j]; // 元素后移
      j--;
    }
    arr[j + 1] = key; // 插入正确位置
  }
  return arr;
}

四、选择排序 (Selection Sort)

原理​​:每次选择未排序部分的最小元素放入已排序末尾
​时间复杂度​​:O(n²)(恒为)
​稳定性​​:不稳定

function selectionSort(arr) {
  for (let i = 0; i < arr.length; i++) {
    let minIndex = i;
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[j] < arr[minIndex]) minIndex = j;
    }
    [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; // 交换位置
  }
  return arr;
}

五、归并排序 (Merge Sort)

原理​​:递归拆分数组,合并有序子序列
​时间复杂度​​:O(n log n)(稳定)
​稳定性​​:稳定

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 = [];
  while (left.length && right.length) {
    result.push(left[0] < right[0] ? left.shift() : right.shift());
  }
  return [...result, ...left, ...right];
}

六、希尔排序 (Shell Sort)

原理​​:动态增量分组优化的插入排序
​时间复杂度​​:O(n^1.3)(平均)
​稳定性​​:不稳定

function shellSort(arr) {
  let gap = Math.floor(arr.length / 2);
  while (gap > 0) {
    for (let i = gap; i < arr.length; i++) {
      const temp = arr[i];
      let j = i;
      while (j >= gap && arr[j - gap] > temp) {
        arr[j] = arr[j - gap];
        j -= gap;
      }
      arr[j] = temp;
    }
    gap = Math.floor(gap / 2);
  }
  return arr;
}

七、计数排序 (Counting Sort)

原理​​:统计元素频次反向填充数组
​时间复杂度​​:O(n + k)(k 为数据范围)
​适用场景​​:整数且范围较小

function countingSort(arr) {
  const max = Math.max(...arr);
  const count = new Array(max + 1).fill(0);
  for (const num of arr) count[num]++;
  const result = [];
  for (let i = 0; i <= max; i++) {
    while (count[i]--) result.push(i);
  }
  return result;
}

总结

  • ​小数据量​​:冒泡/插入/选择排序 (代码简单)
  • ​大数据量​​:快速/归并排序 (高效分治)
  • ​特殊场景​​:计数排序 (整数小范围) 、希尔排序 (部分有序)