排序算法整理

157 阅读2分钟

冒泡

相邻比较大的后移直到移动到最后然后落座。
每次循环记录最后一次交换的位置,下次循环只检查到这个位置。
因为最后交换位置之后的部分都已落座。

let sort = function (arr){
    let len =arr.length;
    while(len > 1){
        let nowLen = 1;
        for (let i=0; i<len ; i++){
            if (arr[i] > arr[i+1]){
                [arr[i],arr[i+1]] = [arr[i+1],arr[i]];
                nowLen = i;
            }
        }
        len = nowLen;
    }
    return arr;
}
  • 复杂度 最好o(n)最坏/平均(n2)

选择排序

选择最小的放第一个入此往复。

  • 复杂度恒为o(n2)

插入排序

从第一个元素开始逐渐加入新的元素排序,加入的元素冒泡到该去的位置。
可以使用二分查找优化寻找指定位置。

  • 最佳情况:输入数组按升序排列。T(n) = O(n)
  • 最坏情况:输入数组按降序排列。T(n) = O(n2)
  • 平均情况:T(n) = O(n2)

希尔排序

把数组分成两个一组,两个元素的间隔相同,对每个组简单选择排序。
合并组为四个一组再排序。
直到所有组被合并。
数组的有序程度指数级提升而非线性提升。

  • 最佳情况:T(n) = O(nlog2 n)
  • 最坏情况:T(n) = O(nlog2 n)
  • 平均情况:T(n) =O(nlog n)

归并排序

分为两个一组逐渐合并。
合并采用两个组的头部(组内最小)取出加入res的方法。

  • 最佳情况:T(n) = O(n)
  • 最差情况:T(n) = O(nlogn)
  • 平均情况:T(n) = O(nlogn)

快排

我称其为二分排序。
但是分区过程采用交换反向检查的方法来避免插入操作造成的大量移位操作。

  • 最佳情况:T(n) = O(nlogn)
  • 最差情况:T(n) = O(n2)
  • 平均情况:T(n) = O(nlogn)

堆排序

将数组转为大顶堆/小顶堆,不断调换位置直到树完成。特点是稳定。

  • 最佳情况:T(n) = O(nlogn)
  • 最差情况:T(n) = O(nlogn)
  • 平均情况:T(n) = O(nlogn)

计数排序

元素范围确定有高重复率时使用,遍历一次数组加入范围排序号的key值桶,遍历一次桶数组生成结果。

  • 复杂度恒为n+k

基数排序

按位数的技术排序,先排序个位再排序十位生成结果。

  • 最佳情况:T(n) = O(n * k)
  • 最差情况:T(n) = O(n * k)
  • 平均情况:T(n) = O(n * k)