将recursionalgorithm转换为迭代algorithm的devise模式

是否有任何通用的启发式,技巧,窍门或常见devise范例可用于将recursionalgorithm转换为迭代algorithm? 我知道这是可以做到的,我想知道这样做是否有值得记住的做法。

您可以完全保留recursionalgorithm的原始结构,但通过使用尾部调用并更改为延续传递来避免堆栈,如本博客条目所示 。 (我应该真的做出一个更好的独立的例子。)

我使用的一种常用技术是用迭代replacerecursionalgorithm的过程,通常是使用堆栈,将传递给recursion函数的参数推送出去。

检查以下文章:

  • 用堆栈replacerecursion
  • 堆栈和recursion消除 (pdf)

一个常见的做法是pipe理一个LIFO栈,它保留一个正在运行的“待完成”列表 ,并在一个while循环中处理整个过程,直到列表为空。
有了这种模式,真正的recursion模型中的recursion调用将被replace为
– 将当前(部分完成)任务的“上下文”推送到堆栈上,
– 将新任务(提示recursion的任务)推送到堆栈上
– 并“继续”(即跳转到while循环的开始处)。 在循环的头部附近,逻辑popup最近插入的上下文,并在此基础上开始工作。

实际上, 这只是“移动”本来会保留在“系统”堆栈上的嵌套堆栈中的信息到应用程序pipe理的堆栈容器。 然而,这是一个改进,因为这个堆栈容器可以在任何地方分配(recursion限制通常与“系统”堆栈中的限制相关联)。 因此,基本上完成了相同的工作,但“堆栈”的显式pipe理允许这发生在单个循环结构内,而不是recursion调用。

经常recursion可以被尾recursion所取代,通过收集累加器中的部分结果并用recursion调用recursionrecursion。 尾recursion本质上是迭代的,recursion调用可以作为跳转来实现。

例如,标准的一般recursion定义的阶乘

 factorial(n) = if n = 0 then 1 else n * factorial(n - 1) 

可以被replace

  factorial(n) = f_iter(n, 1) 

  f_iter(n, a) = if n = 0 then a else f_iter(n - 1, n * a) 

这是尾recursion。 这是一样的

 a = 1; while (n != 0) { a = n * a; n = n - 1; } return a; 

看看这些链接的性能示例

recursionVS迭代(循环):速度和内存比较

用迭代replacerecursion

recursion与迭代

问:recursion版本通常更快吗? 答:不 – 通常速度较慢(由于维护堆栈的开销)

  Q: Does the recursive version usually use less memory? A: No -- it usually uses more memory (for the stack). Q: Then why use recursion?? A: Sometimes it is much simpler to write the recursive version (but 

我们需要等到我们讨论过树才能看到很好的例子…)

我通常从基本案例开始(每个recursion函数都有一个),并向后工作,如果需要,将结果存储在caching(数组或散列表)中。

recursion函数通过求解较小的子问题来解决问题,并使用它们来解决问题的实例。 每个子问题也进一步细分,直到子问题太小,解决scheme变得微不足道(即基本情况)。

这个想法是从基本案例(或基本案例)开始,然后用它来构build更大案例的解决scheme,然后用这些案例来构build更大的案例,直到整个问题得到解决。 这不需要堆栈,可以用循环完成。

一个简单的例子(在Python中):

 #recursive version def fib(n): if n==0 or n==1: return n else: return fib(n-1)+fib(n-2) #iterative version def fib2(n): if n==0 or n==1: return n prev1,prev2=0,1 # start from the base case for i in xrange(n): cur=prev1+prev2 #build the solution for the next case using the previous solutions prev1,prev2=cur,prev1 return cur 

一种模式是尾recursion :

函数调用被称为尾recursion,如果在函数返回后没有任何事情要做,除了返回它的值。

Wiki 。