【问题标题】:Mergesort and recursion合并排序和递归
【发布时间】:2020-03-04 03:00:15
【问题描述】:

所以我正在查看合并排序的代码,我看到了递归的使用,我确实明白他们正在使用分而治之,但我无法理解这一切是如何发生的(即内存是如何得到的分配和数组在内部划分)。如果有人能用任何随机内存地址解释整个过程是如何在堆栈内发生的(每一点就像函数分配了多少内存和递归流程)图像将有很大帮助.

PS-我在谷歌上做了很多尝试来获取一些关于它的信息(搜索“在堆栈内的合并排序中递归的工作”和许多其他东西)并试图自己理解它但不能。在此先感谢花时间和帮助。

【问题讨论】:

  • 你了解调用函数时堆栈上会发生什么吗?不管它是否是递归?如果你不这样做,这对你来说似乎是一个很好的教程:manybutfinite.com/post/journey-to-the-stack
  • this video 提供了出色的视觉表现。每次舞者分成一组代表一个递归调用。
  • @RomanHocke 首先感谢您的帮助,但是当我阅读这篇文章时,我对其中的一些词和东西有点不熟悉,首先什么是缓冲区,图中的 f 0 0 东西是什么..
  • @Code-Apprentice 实际上我知道它是如何分裂的以及它是如何排列的,我不知道它是如何在内存中发生的......
  • @Anonymous286 该视频还显示了数组的分配方式。

标签: c recursion merge stack mergesort


【解决方案1】:

应该注意的是,大多数库都使用自下而上(迭代)合并排序的一些变体,而自上而下(递归)合并排序的大多数实例都是出于教育目的。

自顶向下合并的典型实现实际上并没有“拆分”数组,而是生成表示子数组开始、中间和结束的索引,并在使用递归时有效地将这些索引推入堆栈调用自己。请注意,在创建两个子数组大小 == 1 的基本情况之前,合并不会开始,然后合并和拆分完成,遵循调用链上下,深度优先,左优先。

为了比较,自下而上的归并排序不使用任何递归步骤,而是通过将包含 n 个元素的数组视为大小为 1 的 n 个子数组开始,并立即开始合并偶数和奇数子数组。

自顶向下归并排序的开销并不大,因为递归的时间复杂度为 O(log(n)),而自顶向下和自底向上归并排序的时间复杂度为 O(n log(n))。在合并步骤中,最终子数组变得足够大,以至于大部分时间都花在了自顶向下和自底向上合并排序的相同合并函数上。

【讨论】:

  • 感谢您抽出宝贵的时间回答问题,但您能否通过示例和图表详细说明我的意思...
  • @Anonymous286 - this answer中有示例输出