合并排序、快速排序和树遍历中的递归

Posted

技术标签:

【中文标题】合并排序、快速排序和树遍历中的递归【英文标题】:Recursion in Merge Sort, Quick Sort and traversal of trees 【发布时间】:2015-04-07 22:52:30 【问题描述】:

在学习不同的算法(如合并排序快速排序树遍历)时,我观察到有两个递归调用紧随其后彼此。

我无法完全理解。请简单解释一下为什么我们使用两个递归调用?这是某种模式吗?

还有任何算法可以进行两次以上的立即递归调用吗?

合并排序

m_sort(数字, 温度, 左, 中); m_sort(numbers, temp, mid+1, right);

树遍历

预购(node.left) 预购(node.right)

【问题讨论】:

【参考方案1】:

有两个递归调用,因为同一个函数需要在两个不同的地方执行。在从根开始遍历树的情况下,您希望递归地从左侧向下然后向右向下。函数调用的工作方式是,F 调用preorder(node.left),而对preorder(node.right) 一无所知。当它进入node.left 时,它现在位于B。将一直进行相同的递归调用,直到底部,A。当 preorder(node.left) 从A 返回时然后 B 中的代码调用preorder(node.right) 并且递归将继续。

这与其说是一种模式,不如说是对许多二进制结构进行递归工作的本质,其中采用分治策略将工作分成更小的部分,然后对每个部分分别执行递归直到遇到琐碎的情况(如A中没有子节点的节点,当它返回时)

来源:“Sorted binary tree preorder”Sorted_binary_tree.svg:Miles衍生作品:Pluke(talk)-Sorted_binary_tree.svg。通过Wikimedia Commons 在公共领域获得许可。

【讨论】:

【参考方案2】:

你想调用它两次的原因是因为它把问题分成了两半。

对于排序情况,你想对下半部分和上半部分进行排序。而在树的情况下,你要遍历左轨和右轨。恰好这个数字是 2,因为您在每次递归中将域分成两半。但是您可以将问题拆分为您想要的多少部分,并且某些问题甚至可能在每个递归中具有可变数量的部分。

一个简单的方法可以想象,当你站在一个十字路口时,你会考虑从那里可以去多少个方向,如果你想访问所有的方向,那么你需要调用所有的方向。

【讨论】:

以上是关于合并排序、快速排序和树遍历中的递归的主要内容,如果未能解决你的问题,请参考以下文章

递归与分治-合并排序快速排序以及循环赛问题

php实现快速排序

php实现快速排序

数据结构快速排序非递归实现

优化的归并排序比快速排序更快

混合快速/合并排序对随机数据的性能