我正在阅读将递归算法转换为迭代算法.我遇到了一个博客文章
http://blog.moertel.com/posts/2013-05-11-recursive-to-iterative.html,解释了将递归算法首先转换为尾递归算法然后将尾递归转换为迭代算法的过程.在帖子中,解释了当我们想要将递归算法转换为尾递归算法时,我们应该首先理解递归调用的返回和调用函数的return语句之间发生了什么.完成后,我们应该尝试向递归函数添加一个秘密特征/累加器参数,然后决定返回什么.我已经按照博客文章中给出的示例的概念进行了操作,但我无法解决博客末尾的练习.我无法确定我的累加器参数应该是什么?我应该如何根据累加器参数做出决定.我不想要一个解决方案,但有一些关于如何解决这个问题的指示.这是练习代码:
def find_val_or_next_smallest(bst, x):
"""Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
if bst is None:
return None
elif bst.val == x:
return x
elif bst.val > x:
return find_val_or_next_smallest(bst.left, x)
else:
right_best = find_val_or_next_smallest(bst.right, x)
if right_best is None:
return bst.val
return right_best
提前致谢!
最佳答案 我发布这个来取代我昨天的评论并显示代码.
在递归算法中,每个调用都会创建一个包含函数局部变量和传递参数的堆栈帧.所有堆栈帧一起保存某种状态信息.当您要避免递归时,将不会有额外的堆栈帧.因此,必须在非递归函数中维护数据的重要部分.
现在到代码.我试着严格按照说明操作.
这是原始来源.我刚刚省略了文档字符串,并在ifs返回后立即替换了elifs(只是首选样式的问题).
def find_val_or_next_smallest1(bst, x):
if bst is None:
return None
if bst.val == x:
return x
if bst.val > x:
return find_val_or_next_smallest1(bst.left, x)
else:
right_best = find_val_or_next_smallest1(bst.right, x)
if right_best is None:
return bst.val
return right_best
现在到尾递归.有四个分支.两个非递归,一个已经尾递归,第四个需要重写:
right_best = find_val_or_next_smallest1(bst.right, x)
if right_best is None:
return bst.val
return right_best
该分支选择bst.val或调用结果,以较好者为准.调用必须最后完成,因此必须将bst.val传递给它.该函数获取一个新参数,其含义是“如果找不到更好的东西,则返回此项”.在更改之前,如果您没有找到任何内容,则返回“无”.所以我们只需要替换None值.我调用了新参数,因为它是我们迄今为止发现的.
def find_val_or_next_smallest2(bst, x, found=None):
if bst is None:
return found
if bst.val == x:
return x
if bst.val > x:
return find_val_or_next_smallest2(bst.left, x, found)
else:
return find_val_or_next_smallest2(bst.right, x, found=bst.val)
像博客一样直接转换:
def find_val_or_next_smallest3(bst, x, found=None):
while True:
if bst is None:
return found
if bst.val == x:
return x
if bst.val > x:
bst, x, found = bst.left, x, found
else:
bst, x, found = bst.right, x, bst.val
和清理:
def find_val_or_next_smallest4(bst, x):
found=None
while True:
if bst is None:
return found
if bst.val == x:
return x
if bst.val > x:
bst = bst.left
else:
bst, found = bst.right, bst.val