为什么quicksort的常数因子比heapsort更好?

时间:2013-08-26 18:44:40

标签: performance algorithm sorting

根据我的计算:

  • Quicksort cost = n +(n / 2 + n / 2)+(n / 4 + n / 4 + n / 4 + n / 4)+ ... = n * log(n)= log(n n
  • Heapsort cost = sum [log(i)] i = n,n-1,n-2,...,1 = log(n!)

为什么说quicksort比heapsort有更好的常数因子,因此快速排序比heapsort平均更好?不是log(n n )>的log(n!)?

2 个答案:

答案 0 :(得分:11)

我认为这里的问题是你对quicksort和heapsort的分析不够精确,无法说明为什么常数因素会有所不同。

你的确可以证明,平均而言,quicksort会比heapsort进行更多的比较(对于quicksort而言,大约1.44 n log 2 n,而n log 2 n与heapsort相比)。但是,比较并不是heapsort和quicksort运行时的唯一决定因素。

快速排序更快的主要原因是 locality of reference由于内存缓存的工作方式,在彼此相邻的位置进行的数组访问往往比数组访问散布在整个数组中。在快速排序中,分区步骤通常在数组的末尾执行所有读取和写入操作,因此数组访问彼此密切相关。另一方面,Heapsort在数组上下移动时跳转到数组。因此,平均而言,快速排序中的数组访问所花费的时间比堆栈中的数组访问少得多。差异足够大,以至于快速排序中n log n项前面的常数因子低于heapsort中n log n项前面的常数因子,这是快速排序比快堆更快的一个原因。

简而言之 - 如果我们所关心的只是比较,那么heapsort比quicksort更好。但由于内存系统使用缓存并且缓存未命中是昂贵的,因此快速排序通常是更好的选择。

另外,请注意log(n n )= n log n和log(n!)= n log n - n + O(log n)来自Stirling's approximation。这意味着log(n!)并不比n log n小很多,即使n非常大。肯定存在差异,但它不够大,无法自行制造出巨大的凹痕。

希望这有帮助!

答案 1 :(得分:6)

以下是Steven S. Skiena的算法设计手册中的段落,该手册讨论了三个O(nlogn)排序算法之间的速度:

  

但是我们如何比较两个Θ(n log n)算法来决定哪个算法   更快?我们如何证明quicksort真的很快?不幸,    RAM模型和Big Oh分析提供了太多粗略的工具   做出那种区分。当面对同样的算法时   渐近复杂性,实现细节和系统怪癖等   因为缓存性能和内存大小可能被证明是决定性的   因素。

     

我们可以说的是,实验表明 a   正确实施的快速排序很好地实现了   比mergesort或heapsort快2-3倍。主要原因是   最内层循环中的操作更简单。但我不能   如果你不相信我,当我说快速排序更快时,请与你争辩。   这是一个问题,其解决方案不在我们的分析工具之外   正在使用。最好的方法是实现算法和   实验

-4.6.3“Quicksort真的很快吗?”,算法设计手册