(1) 为什么Quick Sort比Merge Sort快?
因为Quick Sort的复杂度的那个常数小。在我们学习算法复杂度分析的时候,复杂度符号大O,是忽略掉常数的。10000n,100n,2n都是O(n),他们的复杂度是在一个级别的,但是实际性能却不同。同理,归并排序和快速排序都是O(nlogn)级别的,但是快速排序的那个常数更小。具体表现在,快速排序在每一层比较次数比归并排序少。(更不用提归并排序的merge过程,还需要一个辅助空间,将所有的元素都挪一边,而快速排序则完全是原地的。)
这也是快速排序叫“快速”排序的原因:)
(2) 为什么快速排序是不稳定的?
举个例子:
待排序数组:int a[] ={1, 2, 2, 3, 4, 5, 6};
在快速排序的随机选择比较子(即pivot)阶段:
若选择a[2](即数组中的第二个2)为比较子,,而把大于等于比较子的数均放置在大数数组中,则a[1](即数组中的第一个2)会到pivot的右边, 那么数组中的两个2非原序(这就是“不稳定”)。
若选择a[1]为比较子,而把小于等于比较子的数均放置在小数数组中,则数组中的两个2顺序也非原序
这就说明,quick sort是不稳定的。
(3) QuickSort和MergeSort对比
- QuickSort的时间复杂度平均是O(nlogn),但最坏情况下是O(n^2)。MergeSort的时间复杂度严格来说就是O(nlogn)。那为什么实际应用中QuickSort用得多呢?因为MergeSort需用分配额外的O(n)空间,当用到new函数的时候会消耗很多的系统时间。另外像JAVA里面还要garbage collection又消耗一些时间。所以总体上来说MergeSort的overhead更大。
- QuickSort的写法有很多种,每次取pivot可以从中间取,也可以从两边取,也可以弄个随机函数取。QuickSort也可以搞个额外空间。
而MergeSort一定是从中间取。 - QuickSort是不稳定算法,MergegSort是稳定算法。这里稳定是指当数组有重复元素时,排序后的元素仍然能保持之前的顺序。
- QuickSort和MergeSort的复杂度都可以按T(n)=2T(n/2)+O(n)来分析。
QuickSort先做O(n)的部分,再做2T(n/2)的部分。即先整体有序,再局部有序。
MergeSort先做2T(n/2)的部分,再做O(n)的部分。即先局部有序,再整体有序。