有没有通用的启发式算法、技巧、诀窍或常见的设计范例可以用来将递归算法转换为迭代算法?我知道它是可以完成的,但我想知道在这样做时需要牢记哪些实践经验。
有没有通用的启发式算法、技巧、诀窍或常见的设计范例可以用来将递归算法转换为迭代算法?我知道它是可以完成的,但我想知道在这样做时需要牢记哪些实践经验。
通过使用尾调用和改为传递控制权,可以经常完整保留递归算法的原始结构,但避免使用栈,正如这篇博客文章所建议的那样。(我应该真的想出一个更好的独立示例。)
factorial(x)
的递归版本可能在其中某个地方有 return x*factorial(x-1)
,这不是尾调用。相反,它可以转换为 return factorial(state*x, x-1)
,其中 state 是到目前为止的值。在将所有返回语句转换为调用之后,每个尾调用可以转换为 state = state*x; x = x-1; goto start;
。实际上,您不需要使用 goto
,因为您可以使用 while 循环。 - Eyalfactorial(n) = if n = 0 then 1 else n * factorial(n - 1)
可被替换为
factorial(n) = f_iter(n, 1)
并且
f_iter(n, a) = if n = 0 then a else f_iter(n - 1, n * a)
这是尾递归。它与
a = 1;
while (n != 0) {
a = n * a;
n = n - 1;
}
return a;
Q: Is the recursive version usually faster? A: No -- it's usually slower (due to the overhead of maintaining the stack)
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
we'll need to wait until we've discussed trees to see really good examples...)
#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