当前位置: 首页 > 知识库问答 >
问题:

迭代(基于堆栈)快速排序比递归快吗?

钱安和
2023-03-14

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

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

以下是我提到的一些地方,即递归实现优于递归实现:http://www.geeksforgeeks.org/iterative-quick-sort/

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

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

快速排序:迭代或递归

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

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

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

首先检查分区,并堆叠指示两者中较大者的指针。较小分区的指针根本没有堆叠:我们能够做到这一点,因为我们可以保证较小分区始终等效于第二个递归调用,第二个递归调用位于函数的末尾。这带来了第三个优点:可以消除任何后端递归,并用简单循环替换。

评论代码评论

由于递归,它不会扩展:JVM没有尾部调用优化,它只会将方法调用堆栈增长到与要排序的数组成比例的大小,并且对于太大的数组也会失败。(即使对于确实有尾部调用优化的语言/平台,我认为他们也无法将其实际应用于此代码)

这里也有很多基于堆栈/迭代的快速排序实现,但我想程序员这样做只是为了好玩?

共有2个答案

卫皓
2023-03-14

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

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

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

李开宇
2023-03-14

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

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

 类似资料:
  • 我正在尝试使用递归编写快速排序代码,但我得到一个堆栈溢出错误。第二个递归函数给出了连续误差。我只是想不通。

  • 本文向大家介绍Java迭代快速排序程序,包括了Java迭代快速排序程序的使用技巧和注意事项,需要的朋友参考一下 下面是用于迭代快速排序的Java程序 示例 输出结果 一个名为Demo的类包含3个函数,“swap”用于使用临时变量交换值,一个“partition”函数根据主元素值将数组分为两半,以及“quick_sort”函数,该函数使用主元素值并基于该值对数组中的值进行排序。 在main函数中,将

  • 我有一个执行快速排序的应用程序。在我开始给它一些更大的数字(我第一次得到它是10000000)之前,它工作得很好。我知道是由递归引起的,但我不明白为什么我的应用程序会因此而崩溃。如有任何建议,将不胜感激。这是我的密码:

  • 本文向大家介绍C#递归算法之快速排序,包括了C#递归算法之快速排序的使用技巧和注意事项,需要的朋友参考一下 上两片第归算法学习: 1)递归算法之分而治之策略 2)递归算法之归并排序   上一篇学习中介绍了了递归算法在排序中的一个应用:归并排序,在排序算法中还有一种算法用到了递归,那就是快速排序,快速排序也是一种利用了分而治之策略的算法,它由C.A.R发明,它依据中心元素的值,利用一系列递归调用将数

  • 快速排序 from typing import List def quick_sort(arr: List, left, right) -> List: """ 快速排序是对冒泡排序的改进,核心思想是找到一个中值点pivot,然后将小于等于pivot的放在pivot的左边,大于pivot的放在右边,一直递归到无法拆分pivot点。 :param arr: :re

  • 我想比较有多少掉期和比较( 我的泡泡裙: 我的快速排序: 解决方案: