我正在尝试使用DFS而不是BFS编写返回树中最深叶子的深度的代码,每个节点具有任意数量的子节点。它看起来很接近,但下面的代码仍有一些我无法弄清楚的错误(即返回的深度不正确)。有什么帮助吗?
测试树只是:[[1,2,3],[4,5],[6],[7],[8],[],[],[],[]] < / p>
def max_depth_dfs(tree): # DOESN'T WORK
max_depth, curr_depth, Q = 0,0, [0]
visited = set()
while Q != []:
n = Q[0]
more = [v for v in tree[n] if v not in visited]
if not more:
visited.add(n)
curr_depth -= 1
Q = Q[1:]
else:
curr_depth += 1
max_depth = max(max_depth, curr_depth)
Q = more + Q
return max_depth
答案 0 :(得分:1)
我使用try .. catch
来区分树枝和树叶。 更新不再有例外:)
from collections import Iterable
tree = [[1,2,3],[4,5, [1, 6]],[6],[7],[8],[],[],[],[]]
def max_depth(tree, level=0):
if isinstance(tree, Iterable):
return max([ max_depth(item, level+1) for item in tree])
else: # leaf
return level
print max_depth(tree)
答案 1 :(得分:1)
我发现了这个错误!
if not more:
visited.add(n)
curr_depth -= 1
Q = Q[1:]
当您访问节点4时,curr_depth等于2.节点4没有子节点,因此您减少curr_depth并且curr_depth现在等于1。但是,您将访问的下一个节点是节点5,节点5的深度是2而不是1.因此,curr_depth不会记录树中节点的正确深度。
以下解决方案可能会有所帮助。
def max_depth_dfs(tree):
max_depth, curr_depth, Q = 0, 0, [0]
visited = set()
while Q != []:
n = Q[0]
max_depth = max(max_depth, curr_depth)
if n in visited:
curr_depth -= 1
Q = Q[1:]
continue
#print n, curr_depth #show the node and its depth in the tree
visited.add(n)
more = [v for v in tree[n]]
if not more:
Q = Q[1:]
else:
curr_depth += 1
Q = more + Q
return max_depth
答案 2 :(得分:0)
这是非复黑版本:
from collections import Iterable
def max_depth_no_recur(tree):
max_depth, node = 0, iter(tree)
stack = [node]
while stack:
try:
n = node.next()
except StopIteration:
if len(stack) > max_depth:
max_depth = len(stack)
node = stack.pop()
continue
if isinstance(n, Iterable):
stack.append(node)
node = iter(n)
return max_depth
答案 3 :(得分:0)
考虑到我从Alex和Adonis获得的所有良好反馈并完善代码后,我目前拥有当前版本:
def max_depth_dfs(tree): # correct
max_depth, curr_depth, Q = 0, 0, [0]
visited = set()
while Q != []:
n = Q[0]
if n in visited:
Q = Q[1:]
curr_depth -= 1
visited.remove(n) # won't go back, save memory
print 'backtrack from', n
continue
# proper place to print depth in sync with node id
print 'visiting', n, 'children=', tree[n], 'curr_depth=', curr_depth, 'Q=', Q,
print visited # only current path, instead of visited part of tree
if tree[n]:
visited.add(n) # if leaf, won't ever try to revisit
Q = tree[n] + Q
curr_depth += 1
max_depth = max(max_depth, curr_depth) # no need to check if depth decreases
else:
Q = Q[1:] # leaf: won't revisit, will go to peer, if any, so don't change depth
print 'no children for', n
return max_depth