【问题标题】:Why is quicksort faster in average than others?为什么快速排序平均比其他更快?
【发布时间】:2010-11-26 22:46:43
【问题描述】:

众所周知,快速排序的平均性能为 O(n*log(n)),但合并和堆排序的平均性能也为 O(n*log(n))。所以问题是为什么快速排序平均更快。

【问题讨论】:

  • 堆排序在最坏的情况下是 O(n*log(n)) - 可能在所有情况下。

标签: arrays algorithm performance sorting quicksort


【解决方案1】:

Wikipedia suggests:

通常,快速排序显着 在实践中比其他 O(nlogn) 更快 算法,因为它的内循环可以 在大多数情况下得到有效实施 架构,以及在大多数现实世界中 数据,可以进行设计 最小化概率的选择 需要二次时间。 此外,快速排序往往会使 出色的内存使用率 层次结构,充分利用 虚拟内存和可用缓存。 虽然快速排序不是就地 排序并使用辅助内存,它是 非常适合现代计算机 架构。

还可以查看同一页面上的comparison with other sorting algorithms

另请参阅 CS 网站上的 Why is quicksort better than other sorting algorithms in practice?

【讨论】:

  • 你知道它是如何“利用虚拟内存和缓存”的吗?有什么例子吗?
  • 算法按顺序遍历,这使得locality of reference (en.wikipedia.org/wiki/Locality_of_reference) 可以很好地工作(从而加快工作速度)
  • 由于缓存行大小的原因,顺序读取内存的算法可能已经在(快速)缓存中提供了下一个项目。与遍历内存位置的算法相比,为什么不能影响速度呢?
  • @Michael:快速排序在缓存方面有两个优点。首先是顺序访问——读取和写入点以一种方式在内存中移动,这意味着您一次只能访问几页,并且预取很有可能工作。比较像插入排序中的二进制搜索这样的东西,它不会访问很多位置(在每次传递中),而是访问分散的位置,因此每次访问可能会更慢。其次,自上而下的递归提供了一种缓存遗忘形式——一旦你正在处理的部分小于一个页面,一切都会大大加快。
  • (并不是说插入排序是我们要比较的 n log n 排序之一,但实际上快速排序和插入排序之间的比较非常重要,因为通常使用快速排序你想切换到插入以惊人的大数组大小排序,其中插入变得更快)。合并排序也是顺序访问。当然,堆排序有一些访问结构,但有点到处都是。
【解决方案2】:

快速排序的最坏情况实际上比堆排序和归并排序更差,平均而言,快速排序更快。

至于为什么,需要时间解释,所以我会参考Skiena, The algorithm design manual.

总结快速排序与合并/堆排序的引用:

当面对相同渐近复杂度的算法时,实现 缓存性能和内存大小等细节和系统怪癖可能 很好的证明是决定性的因素。 我们可以说的是,实验表明,在正确实施的地方 快速排序实现得很好,它通常比合并排序快 2-3 倍或 堆排序。主要原因是最内层循环中的操作是 更简单。但是当我说快速排序是 快点。这个问题的解决方案超出了我们正在使用的分析工具。 最好的判断方法是实现算法和实验。

【讨论】:

    【解决方案3】:

    Timsort 可能是better 选项,因为它针对一般排序时看到的数据类型进行了优化,在 Python 语言中,数据通常包含预排序项的嵌入“运行”。它最近也被 Java 采用了。

    【讨论】:

      猜你喜欢
      • 2018-03-28
      • 2011-11-30
      • 2021-07-27
      • 2017-03-18
      • 2018-05-24
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多