用堆栈替换递归DFS树遍历?

时间:2015-01-05 01:53:36

标签: python algorithm recursion stack

众所周知,可以使用递归(例如,在Python中)通过DFS(预订)遍历树:

def DFS(node):
    if node==None:
       return 0
    valueLeft=DFS(node.left)
    valueRight=DFS(node.right)
    return max(valueLeft,valueRight)+1

如果我们调用DFS(root),此代码显然会从树根开始计算树的高度。但是有一个问题(...在一些机器python中有限的递归堆栈大小,所以这个代码溢出检查leetcode中的抱怨......)。

出于好奇以及修复leetcode问题,怎样才能将带有值返回的上述双分支递归转换为使用堆栈的迭代调用?我认为这是可能的,因为无论如何使用堆栈实现递归。我从第1天开始就在课堂上讲过,但从未见过一个代码,特别是对于带有返回值的多分支递归...

我会提前感谢任何帮助过的人。

2 个答案:

答案 0 :(得分:2)

您可以将堆空间用于堆栈 - 基本上维护您自己的堆栈:

def dfs2(root):
  stack = [(root,0)]
  depth = 0
  while stack:
    node, d = stack.pop()
    if node == None:
      depth = max(depth,d)
    else:
      stack.push( (node.left, d+1) )
      stack.push( (node.right, d+1) )
  return depth

答案 1 :(得分:0)

结帐http://stromberg.dnsalias.org/svn/treap/trunk/m4_treap.m4。它在iterator_macro中进行树遍历而不进行递归。

不要让文件扩展名欺骗你 - 它的m4,但它是m4预处理的python,这样我就可以将同一个宏用于多种非递归遍历 - 特别是iterkeys, itervalues和iteritems,m4中没有很多样板。

最终,省略了m4,以便python解释器只能看到python代码。

在同一模块中,reverse_iterator也进行非递归遍历。如果你想忽略其他人的m4-ness,这可能是一个更简单的地方。

你也可以使用sys.setrecursionlimit(size)来增加python解释器的堆栈深度,不过我认为pypy几乎忽略了这一点。 CPython尊重它。