我的教授在课堂上给了我们这个练习,并要求准确地模仿带栈的递归调用。这是递归算法:
def algo(T, h):
ret = -1
s = 0
d = 0
if T != None:
if T.left != None:
s = algo(T.left, h + 1)
if T.right != None:
d = algo(T.right, h + 1)
if s == 0 and d == 0:
ret = h
else:
ret = s + d
return ret
这是我尝试解决此问题的尝试(我使用了两个堆栈,一个用于保存T,另一个用于保存“ s”)
def algo_it(T, h):
ret = -1
s = 0
d = 0
curr = T
next = None
last = None
stack_T = Stack()
stack_S = Stack()
while curr != None or not stack_T.empty():
if curr != None:
# First time entering the function
ret = -1
s = 0
d = 0
if curr.left != None:
# Left recursive call
h = h + 1
next = curr.left
# Save current T because it will be popped when going up
# on recursion tree
stack_T.push(curr)
elif curr.right != None:
# Right recursive call
h = h + 1
next = curr.right
stack_T.push(curr)
else:
# Force going up on recursion tree
next = None
else:
# Coming up from recursion tree
curr = stack_T.top()
if last != curr.right and curr.right != None:
# We're here from the 1st recursive call (left)
# We have to go in right recursive call now
h = h + 1
next = curr.right
# We are returning from left, so ret = s = algo(T.left, h + 1)
s = ret
stack_S.push(s)
ret = -1
d = 0
else:
stack_T.pop()
if curr.right != None:
s = stack_S.pop()
d = ret
else:
s = ret
d = 0
if s == 0 and d == 0:
ret = h
else:
ret = s + d
last = curr
curr = next
return ret
算法失败,因为在stack_S.pop()
上,当堆栈为空时我弹出,因此出现运行时错误。我快要找到解决方案了吗?
非常感谢您的所有帮助!
答案 0 :(得分:1)
当模仿递归调用时,您只压入了您知道应该返回的堆栈。但是,您并不是要让上下文知道将响应推送到哪个上下文。
我建议您分多个步骤来解决此问题。
T
,h
,ret
,s
和d
)转换为递归函数之外的堆栈显式弹出/推送,而不是声明它们,并期望它们在函数结束时消失。 (提示:将ret
留在堆栈上,并在操作stack_s
或stack_d
时将其弹出。)这可能需要为第一个递归调用创建一个辅助函数。ret
堆栈的顶部。)这是一个漫长但机械的过程。它应该使您对计算机通常为您完成的工作量有所赞赏。 :-)