各排序算法表格比较

基本上排序算法,基于选择的排序除了希尔,快排,归并,堆排序之外没啥实用性,只不过是练手的工具罢了,像 O(n^2) 这样过高的时间复杂度,已经失去了它的实用意义了

排序类别 排序算法 平均时间复杂度 最好情况 时间复杂度 最坏情况 时间复杂度 空间复杂度 稳定性 适用场景
交换排序 冒泡排序 O(n^2) O(n) O(n^2) O(1) 稳定 数据基本有序,数据量不大,要求稳定的情况下
选择排序 简单选择排序 O(n^2) O(n^2) O(n^2) O(1) 不稳定 数据基本有序,数据量不大的情况下
插入排序 直接插入排序 O(n^2) O(n) O(n^2) O(1) 稳定 数据基本有序,数据量不大,要求稳定的情况下
插入排序 折半插入排序 O(n^2) O(n) O(n^2) O(1) 稳定 数据基本无序,数据量大的情况下
插入排序 希尔排序 O(n^1.3) O(n) O(n^2) O(1) 不稳定 数据基本无序,数据量大的情况下
交换排序 快速排序 O(nlogn) O(nlogn) O(n^2) O(logn)~O(n) 不稳定 数据基本无序,数据量大的情况下
选择排序 堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定 数据量基本较大情况下
内部排序 归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定 数据量大,且要求稳定的情况下
内部排序 基数排序 O(nk) O(nk) O(nk) O(n+k) 稳定 适用于特定场景,有基数的条件下
内部排序 桶排序 O(n+k) O(n+k) O(n^2) O(n+k) 稳定 适用于特定场景,稳定的,跨度不大的,浮点数的场景
内部排序 计数排序 O(n+k) O(n+k) O(n+k) O(k) 稳定 适用于特定场景,稳定的,跨度不大的,非浮点数的场景
各类排序算法场景分析

基本无实用性的排序算法

冒泡排序,简单选择排序,直接插入排序,折半插入排序。

这几种排序也是最简单的几种排序,由于平均时间复杂度达到了 O(n^2) 所以基本是不会去用了

具有实用性的基于比较的排序

快速排序,希尔排序,归并排序,堆排序

实际排序速率:快速排序 优于 归并排序 优于 希尔排序 优于 堆排序

各类排序算法比较分析_其他

时间复杂度能达到 O(n) 的超高效排序

当 k 不大时,基数排序,桶排序,计数排序都可以达到 O(n) 的时间复杂度,但是我们为什么不大量使用他们呢,因为它们都是需要对排序的数据有严格的场景要求

应用最广泛的排序算法

快速排序,因为其排序速度是极快的,平均时间复杂度可以达到 O(nlogn),也没什么场景限制,所以快排还是比较完美的

理论上最优秀的排序

堆排序(理论最快)

为什么说堆排序是理论上最优呢,因为它理论上我们可以看到它的平均,最好,最差时间复杂度都是比较排序的下界,而且还是一个就地排序,空间复杂度为 O(1),理论上快排最差可以达到 O(n^2) 的时间复杂度,而且快排空间复杂度可以达到 O(logn) 到 O(n)。那为何实际中快排要更快呢?是因为快排很少能达到最差时间复杂度的场景,所以很难达到 O(n^2) 的时间复杂度,再一个就是堆排序比较的几乎都不是相邻的元素,所以它对 cache 这种结构来讲是很不友好,所以实际使用中要比快排慢,实际使用会发现它也比归并,希尔慢

实际中最快的排序算法

快速排序(实际最快)

占用空间最少的排序算法中最快的

希尔排序(空间最少中的最快)

稳定的排序算法中最快的

归并排序(稳定中的最快)

综合能力最好的排序

快排和希尔排序

速度上:快速排序 > 归并排序 > 希尔排序 > 堆排序

空间上:希尔排序 > 堆排序 > 快速排序 > 归并排序

综合比较后发现快排和希尔这两个是最好的排序,那为什么写快排的多呢,因为希尔排序涉及到一个如何选取增量的问题,这个就涉及到数学方面的论证了,比较麻烦。

所以在我们更注重时间而忽视空间的时候我们建议采用快排,当我们非常注重空间,不是特别在意时间的我们建议使用希尔排序

一些解释

内部排序与外排序

内部排序就是可以在内存中完成的排序,一般所说的排序都是内排序,但是数据量太大,内存存不下这么多数据,只能使用到外排序了,外排序如多路归并排序

基于比较和基于数据分配

基于比较的排序时间复杂度下界是 O(nlogn),基于数据分配的排序时间复杂度则可以突破下界

排序算法稳定性的意义

若仅仅是对数字排序,稳定性就显得毫无意义,稳定的排序算法用于即使数值是一样,但是对于初始位置是有意义的场景中