Optimization 迭代(基于堆栈的)快速排序是否比递归更快?

Optimization 迭代(基于堆栈的)快速排序是否比递归更快?,optimization,recursion,quicksort,Optimization,Recursion,Quicksort,在很多地方,我都看到过使用堆栈实现快速排序比使用递归更快的说法。这是真的吗?我知道编译器通常擅长将递归转换为迭代,但页面上的评论称它太复杂,无法优化 对于快速排序还有哪些其他优化 下面是我提到的一些地方,即递归实现比递归实现更好: 尽管进行了上述优化,该函数仍保持递归并使用 用于存储l和h中间值的函数调用堆栈。这个 函数调用堆栈将其他簿记信息与 参数。此外,函数调用还涉及存储等开销 调用方函数的激活记录,然后继续执行 上述函数可以很容易地转换为迭代版本 辅助堆栈的帮助 我知道递归算法总是比它

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

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

下面是我提到的一些地方,即递归实现比递归实现更好:

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

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

我知道递归算法总是比它们的算法慢 迭代对应项。
然而,答案指出这并不总是正确的,尽管我不明白为什么要为在系统堆栈上存储函数状态所涉及的开销设置参数

使用显式堆栈和迭代代替递归实现的优点主要有三个方面:

首先检查分区,指针指示其中较大的分区 这两个是堆叠的。较小分区的指针没有堆叠 总之:我们能够做到这一点,因为我们可以保证较小的 分区总是相当于第二个递归调用, 它位于函数的末尾。这导致了第三个问题 优点: 任何尾端递归都可以消除,并用一个简单的循环代替

由于递归,它不会扩展:JVM没有尾部调用 优化后,它将简单地将方法调用堆栈增长到某种程度 与要排序的数组成比例,并且对于太大的 数组。(甚至对于有尾部调用的语言/平台 我不认为他们能把它应用到这件事上 代码)


还有很多基于堆栈/迭代的quicksort实现,但我想编码人员这样做只是为了好玩?

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


请提供正确的链接,指向解释堆栈比递归快的原因的参数。没有这一点我们无法回答。

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

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


有些编译器会自己尝试优化递归算法。但就像几乎所有的优化案例一样:不确定哪种算法会更快。

你的基准测试告诉你什么?比较苹果和桔子?你的意思是迭代还是递归?@MarkRansom我的大脑告诉我,这是一种将基准测试留给后者的情况,在随意散列代码并将其扔进基准测试程序之前,先对此进行一些理论思考。@leppie我认为迭代快速测试确实实现了堆栈,所以从这个意义上说是的。Ok更新了链接。我听到的另一个论点是,对于快速排序,堆栈可以比系统堆栈更有效地实现(可能是定制的一种情况)。这对我来说没有意义,因为堆栈不是很简单,一个实现比另一个实现更好是没有意义的吗?
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