算法学习(8):排序算法总结

排序算法总结

排序算法总结表

算法名称 时间复杂度 额外空间复杂度 能否做到稳定性
选择排序
O(N2)
O(1)
冒泡排序
O(N2)
O(1)
插入排序
O(N2)
O(1)
归并排序
O(NlogN)
O(N)
快速排序(3.0版)
O(NlogN)
O(logN)
堆排序
O(NlogN)
O(1)

排序算法的选择

  • 一般来说选择快速排序,虽然归并、快排、堆排时间复杂度一样,但是经过实验,快速排序的常数时间最快。
  • 对额外空间复杂度要求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库的排序算法中,基础类型(整数数组)会调用快速排序,非基础类型会调用归并排序,就是因为基础类型默认稳定性没用,非基础类型的稳定性有用。这种底层代码其实很长,恨不得所有排序的优势都给用上

posted @ 2022-07-20 15:30  小肉包i  阅读(14)  评论(0)    收藏  举报