面试时有人问了我这个问题。它们都是O(nlogn)的,但大多数人使用快速排序而不是归并排序。为什么呢?
面试时有人问了我这个问题。它们都是O(nlogn)的,但大多数人使用快速排序而不是归并排序。为什么呢?
与归并排序不同,快速排序不使用辅助空间。而归并排序使用的辅助空间为O(n)。 但是,归并排序的最坏时间复杂度为O(nlogn),而快速排序的最坏情况复杂度为O(n^2),当数组已经排序时会发生。
为什么快速排序很好?
快速排序总是比归并排序更好吗?
并非如此。
注意:在Java中,Arrays.sort()函数对于基本数据类型使用快速排序,对于对象数据类型使用归并排序。因为对象会占用内存开销,所以对于性能而言,为归并排序增加一点点额外的开销可能没有问题。
参考资料:观看Coursera普林斯顿算法课程第三周的快速排序视频
就原始值而言,随着DualPivotQuickSort的改进,答案会稍微倾向于快速排序。在JAVA 7中,它被用于在java.util.Arrays中进行排序。
It is proved that for the Dual-Pivot Quicksort the average number of
comparisons is 2*n*ln(n), the average number of swaps is 0.8*n*ln(n),
whereas classical Quicksort algorithm has 2*n*ln(n) and 1*n*ln(n)
respectively. Full mathematical proof see in attached proof.txt
and proof_add.txt files. Theoretical results are also confirmed
by experimental counting of the operations.
当我尝试使用这两种排序算法并计算递归调用次数时,快速排序比归并排序始终具有更少的递归调用次数。这是因为快速排序有枢轴点,而枢轴点不包含在下一个递归调用中。这样,快速排序可以更快地达到递归基本情况,而不像归并排序那样需要更多的递归调用。
qsort
、Python的list.sort
以及Firefox JavaScript中的Array.prototype.sort
都是强化版的归并排序。(GNU STL的sort
使用Introsort,但这可能是因为在C++中,交换操作可能比复制操作更加高效。) - Jason Orendorff