1.回顾几种排序算法
线性排序虽然时间复杂度比较低,但是对数据的要求也比较高,所以就不适合用来作为通用的排序函数的实现算法。对于小规模数据排序,可以选择时间复杂度是O()的排序算法;如果是大规模数据的排序,可以选择时间复杂度是O(nlogn)的排序算法。
2.为什么归并排序比快排使用的情况少?
快排在最坏的情况下,时间复杂度是O(),归并排序不管是在平均情况还是最坏情况,时间复杂度都是O(nlogn),为什么却不受重用呢?
归并排序不是原地排序算法,也就是说不是空间复杂度为O(1)的算法,在排序的过程中,除了数据的存储占有空间以外,为了排序还需要额外的空间消耗。
3.如何优化快速排序?
3.1 选择合理的分区点
快速排序在最坏的情况下,时间复杂度是O(),这种O()时间复杂度出现的主要原因是因为分区点选择不够合理。
最理想的分区点是:被分区点分开的两个分区中,数据的数量差不多。
两个比较常用、比较简单的分区方法:
- 三数取中法(从区间首、尾、中间,分别取三个数,然后对比大小,取这三个数的中间值作为分区点)
- 随机法(从要排序的区间随机选择一个元素作为分区点,站在概率论的角度,最坏情况出现的概率是比较低的)
3.2 递归要警惕堆栈溢出
快速排序使用递归来实现的,为避免快速排序的过程中,出现递归过深而堆栈过小,导致堆栈溢出,我们有两种解决办法:
- 限制递归深度(一旦递归深度超过阈值,就停止递归)
- 通过在堆上模拟实现一个函数调用栈,手动模拟递归压栈、出栈的过程,这样就没有了系统栈大小的限制。(不太能理解)