算法学习(8):排序算法总结
排序算法总结
排序算法总结表
| 算法名称 | 时间复杂度 | 额外空间复杂度 | 能否做到稳定性 |
|---|---|---|---|
| 选择排序 | |||
| 冒泡排序 | |||
| 插入排序 | |||
| 归并排序 | |||
| 快速排序(3.0版) | |||
| 堆排序 |
排序算法的选择
- 一般来说选择快速排序,虽然归并、快排、堆排时间复杂度一样,但是经过实验,快速排序的常数时间最快。
- 对额外空间复杂度要求O(1)的时候,选择堆排序
- 需要保证稳定性时选择归并排序
排序算法目前的研究现状
1.基于比较的排序时间复杂度不能做到O(NlogN)以下
2.如果保证时间复杂度为O(NlogN),则不能做到空间复杂度O(N)以下且保证稳定性。空间复杂度和稳定性如果想要其中一个更好,则必须牺牲另外一个或时间复杂度变得更差
例如:
- 归并排序的额外空间复杂度可以通过“归并排序内部缓存法”变成0(1),但是非常难且会损失稳定性
- 某些所谓的“原地归并排序”虽然可以做到额外空间复杂度为0(1),但是时间复杂度会变成O(N2)
- 快速排序可以做到稳定性,但是非常难,是论文级别的(“01 stable sort”),而且还会把空间复杂度变成O(N)
- 某编程题,整型数组,要求奇数放在左边,偶数放在右边,保证稳定性。经典的快速排序partition中是小于num的放在左边,大于num的放在右边,这是01标准,奇偶也是01标准,只有上面提到的论文可以做到,太难了。
工程上对排序的改进
充分利用O(NlogN)和O(N2)排序各自的优势
某些快速排序的算法中可以看到当样本量小于60时,会直接采用插入排序。这是因为虽然插入排序的时间复杂度更大,但是当小样本量的时候插入排序比快速排序更快。
稳定性的考虑
在C++的STL库的排序算法中,基础类型(整数数组)会调用快速排序,非基础类型会调用归并排序,就是因为基础类型默认稳定性没用,非基础类型的稳定性有用。这种底层代码其实很长,恨不得所有排序的优势都给用上
浙公网安备 33010602011771号