【问题标题】:Is iterative (stack based) quick sort faster than recursive?迭代(基于堆栈)快速排序是否比递归更快?
【发布时间】:2014-09-05 04:27:03
【问题描述】:

在很多地方,我都看到使用堆栈实现快速排序比使用递归更快的说法。这是真的?我知道编译器通常擅长将递归更改为迭代,但是链接到页面上的 cmets 声称它太复杂而无法优化。

快速排序还有哪些其他优化?

以下是一些我认为迭代实现优于递归实现的地方: http://www.geeksforgeeks.org/iterative-quick-sort/

尽管进行了上述优化,该函数仍然是递归的并使用 函数调用堆栈来存储 l 和 h 的中间值。这 函数调用堆栈将其他簿记信息与 参数。此外,函数调用涉及存储等开销 调用函数的激活记录,然后恢复执行。

上面的函数可以很容易地转换为迭代版本 辅助堆栈的帮助。

Quicksort : Iterative or Recursive

我了解到递归算法总是比他们的算法慢 迭代对应。
然而,答案指出这并不总是正确的,尽管我不明白为什么要为将函数状态存储在系统堆栈上所涉及的开销提出论点。

使用显式堆栈和迭代代替递归实现的优势本质上是三个方面:

http://www.codeproject.com/Articles/23196/Iterative-Quick-Sort

Using an explicit stack allows the sort to avoid the temporary storage of unnecessary information.
Rather than placing two partitions on a stack in arbitrary order, as a typical recursive Quicksort would implicitly do, the sizes of the

首先检查分区,指针指示较大的 两者是堆叠的。较小分区的指针未堆叠 完全:我们能够做到这一点,因为我们可以保证较小的 partition 总是等价于第二个递归调用, 它位于函数的末尾。这导致第三 优势: 任何尾端递归都可以消除并用一个简单的循环替换。

Comment on codereview

由于递归,它不会扩展:JVM 没有尾调用 优化,它只会将方法调用堆栈增加到某些东西 与要排序的数组成正比,并且它会因太大而失败 大批。 (甚至对于确实有尾调用的语言/平台 优化我认为他们无法将其实际应用于此 代码)

还有很多基于堆栈/迭代的快速排序实现 here,但我猜编码人员这样做只是为了好玩?

【问题讨论】:

  • 你的基准测试告诉你什么?
  • 比较苹果和橘子?你不是说迭代还是递归?
  • @MarkRansom 我的大脑告诉我,这是一种将基准测试留给后者并给出一些理论思考的情况,然后再随意散列代码并将其撞到基准测试器中。
  • @leppie 我认为迭代快速排序确实实现了堆栈,所以从这个意义上说是的。

标签: optimization recursion quicksort


【解决方案1】:

您给我们的链接并没有说在 Java 中使用堆栈更快,它说 JVM 将堆栈溢出一个大的排序数组。顺便说一句,大多数(所有?)递归都是用堆栈实现的。

请给出正确的链接指向解释为什么堆栈比递归更快的参数。没有这个我们无法回答。

【讨论】:

  • 好的,更新了链接。我听到的另一个论点是,对于快速排序,堆栈可以比系统堆栈更有效地实现(也许是定制的一个案例)。这对我来说没有意义,因为堆栈不是那么简单以至于一个实现比另一个更好没有意义吗?
【解决方案2】:

递归算法几乎总是基于堆栈的:它们使用“调用堆栈”,只有在尾递归的情况下,最后的调用记录才会被覆盖。使用递归的潜在优化是增加调用堆栈是单个 CPU 指令。因此,在硬件支持方面,有时递归算法会更快。

在大多数情况下,您可以优化堆栈(例如,因为某些参数(例如要排序的数组)仍然相同,或者因为只有一个返回地址)。如果是这种情况,显式堆栈会更快。

一些编译器会尝试自己优化递归算法。但与几乎所有优化情况一样:无法确定哪种算法会更快。

【讨论】:

    猜你喜欢
    • 2020-08-14
    • 2012-09-15
    • 2013-09-21
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多