文章目录
基本上排序算法,基于选择的排序除了希尔,快排,归并,堆排序之外没啥实用性,只不过是练手的工具罢了,像 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),基于数据分配的排序时间复杂度则可以突破下界
排序算法稳定性的意义
若仅仅是对数字排序,稳定性就显得毫无意义,稳定的排序算法用于即使数值是一样,但是对于初始位置是有意义的场景中