对排序算法的总结和提升

 
通过前面章节的学习,读者已经掌握了常用的几种排序算法,包括冒泡排序插入排序选择排序希尔排序归并排序快速排序等,接下来带大家快速梳理一下。

时间复杂度

下表罗列了不同排序算法的时间复杂度。
表1:排序算法的时间复杂度
排序算法 时间复杂度
最优 平均 最差
冒泡排序算法 O(n) O(n2) O(n2)
插入排序算法 O(n) O(n2) O(n2)
选择排序算法 O(n2) O(n2) O(n2)
希尔排序算法 O(nlogn) O(nlogn) O(n2)
归并排序算法 O(nlogn) O(nlogn) O(nlogn)
快速排序算法 O(nlogn) O(nlogn) O(n2)
计数排序算法 O(n+k),k是输入数据的范围 O(n+k) O(n+k)
基数排序算法 O(d(n+k)),d 是最大数字的位数 O(d(n+k)) O(d(n+k))
桶排序算法 O(n+k),k 是桶的数量 O(n+k) O(n2)

稳定性

对于给定的待排序序列,经常会包含相同的元素,例如:

3 1 2 4 2

序列中包含两个元素 2,为了区分它们,我们分别称它们为 "红 2" 和 "绿 2",它们的相对位置是:红 2 位于绿 2 的左侧,或者说绿 2 位于红 2 的右侧。

如果使用某种排序算法对序列进行排序,得到的有序序列是:

升序序列:
1 2 2 3 4
降序序列:
4 3 2 2 1

红 2 依然位于绿 2 的左侧,它们的相对位置保持不变,表明当前使用的排序算法是稳定的;反之,如果红 2 和绿 2 的相对位置发生了改变,那么这个排序算法就是不稳定的。

下表罗列了不同排序算法的稳定性。

表2:排序算法的稳定性
排序算法 稳定排序算法
冒泡排序算法 稳定
插入排序算法 稳定
希尔排序算法 不稳定
选择排序算法 不稳定
归并排序算法 稳定
快速排序算法 不稳定
计数排序算法 稳定
基数排序算法 稳定
桶排序算法 稳定

注意,表格中标记“稳定”的排序算法,比如计数排序、基数排序、桶排序等,受实现思路的影响,也可能变得不稳定。

以桶排序算法为例,如果各个桶内存储相同元素时改变了它们的相对位置,又或者桶内排序时采用了不稳定的排序算法,那么整个算法就不是稳定的。

原地排序

所谓原地排序,指的是算法在排序过程中,主要使用待排序序列占用的内存空间,最多额外创建几个辅助变量,而不再申请过多的内存空间。

更直白一点讲,直接修改待排序序列本身,把原有的待排序序列变得有序,这样的排序算法就是原地排序的。

原地排序算法的空间复杂度为 O(1)。

下表给大家罗列了哪些排序算法是原地排序的。

表3:原地排序算法
排序算法 原地排序
冒泡排序算法
插入排序算法
希尔排序算法
选择排序算法
归并排序算法 不是
快速排序算法
计数排序算法 不是
基数排序算法 不是
桶排序算法 不是