一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第24天,点击查看活动详情。
总结
一般来说选择排序的话会选择快速排序,因为虽然时间复杂度都是一个级别,但是他的常数项经过试验之后已经验证为比较低的,能用快排就快排。缺点是没有稳定性和空间复杂度。
如果对空间敏感再选择堆排序。
最后对稳定性有要求可以选择归并排序。
一些关注问题
基于比较的排序能不能时间复杂度做到O(N*logN)以下?
目前来说没有,不行
基于比较排序,时间复杂度做到O(N*logN)且空间复杂度O(N)以下且稳定性?
不行,目前也没有,选择任何一个排序都是有一定代价的,看你更加关注哪一点,愿意牺牲哪一点
常见的坑
1:可以做到,但是没必要,这种改进会丧失稳定性,不如直接选择堆排序
2:所谓原地归并排序虽然可以降低空间复杂度到O(1),但是时间复杂度会升高到N^2级别,也根本没有必要,还不如插入
3:有一遍论文可以做到,但是也会让快排空间复杂度上升到O(N)水平!也没啥意义,还不如归并
5:为啥不行可以参考快速排序,快速排序也是0-1partition,可以改成奇数偶数partition:
0-1的statable sort是很难的,快速排序的partition没办法做到稳定性但是和这个奇偶问题是一种策略,所以快排做不到,一般情况下也做不到,只有论文级别算法才能处理
工程上对排序的改进
充分利用两种复杂度排序的优势
可以看一个下面的改进:
意思就是样本量大的时候利用快排的调度思想进行左右递归,但是在小样本量范围上就直接进行插入排序,两个排序的有机整合。这是因为小样本量时插入排序的N^2耗时不明显,但是插入排序的常数时间极小,相比较优势更大。 --> 一种利用排序各自的优势进行的综合排序
其实归并排序也可以进行上面的优化~
稳定性的考虑
有时候会问:系统提供的sort函数,在你是基础类型时候给你用快排,其他类型给你基于归并进行排序,为啥?
就是因为稳定性,因为基础类型的稳定性没啥用,会给你使用常数时间很低的快排。
一些语言例如C语言底层的排序算法代码量都是很多的,里面综合了很多排序算法的优势并且针对的数据情况也分开进行了针对性优化,使用综合排序策略