二叉树每个叶子节点的路径

16

上述函数AllPaths()将包含二叉树每个叶子节点路径的数组追加到全局数组res中。

代码运行良好,但我想移除全局变量res并使函数返回一个数组。该如何操作?

class Node:
    def __init__(self, value, left=None, right=None) -> None:
        self.value = value
        self.left  = left
        self.right = right

res = []
def allPaths(node, arr=[]):
    if node:
        tmp = [*arr, node.value]
        if not node.left and not node.right: # Leaf
            res.append(tmp)
        allPaths(node.left, tmp)
        allPaths(node.right, tmp)


root             = Node(1)
root.left        = Node(2);
root.left.left   = Node(4);
root.left.right  = Node(5);
root.right       = Node(3);
root.right.right = Node(6);
"""
          1         <-- root
        /   \
       2     3  
     /   \    \
    4     5    6    <-- leaves
"""
allPaths(root)
print(res)
# Output : [[1, 2, 4], [1, 2, 5], [1, 3, 6]]

1
请注意,您可以直接使用“root = Node(1,Node(2,Node(4),Node(5)),Node(3,None,Node(6)))”构建树。 - Stef
4个回答

12

一个简单的方法是使用生成器,按照值来产生结果,这样就可以避免使用内部列表和全局列表。然后你可以将其传递给list函数,以得到最终结果:

class Node:
    def __init__(self, value, left=None, right=None) -> None:
        self.value = value
        self.left  = left
        self.right = right

def allPaths(node):  
    if node:
        if not node.left and not node.right: # Leaf
            yield [node.value]
        else:
            yield from ([node.value] + arr for arr in allPaths(node.left))
            yield from ([node.value] + arr for arr in allPaths(node.right))
              
root             = Node(1)
root.left        = Node(2);
root.left.left   = Node(4);
root.left.right  = Node(5);
root.right       = Node(3);
root.right.right = Node(6);
        
g = allPaths(root)
list(g)

# [[1, 2, 4], [1, 2, 5], [1, 3, 6]]

5

一种方法是通过回溯来完成:

def allPaths(node, partial_res, res):
    if not node: 
        return
    if not node.left and not node.right:
        res.append(partial_res[:] + [node.value])
        return    
    partial_res.append(node.value)
    allPaths(node.left, partial_res, res)
    allPaths(node.right, partial_res, res)
    partial_res.pop()

res = []
allPaths(root, [], res)
print(res)

2
移除全局变量res的操作进行得如何? - duTr
函数所需的一切都包含在它的参数中。你可以将其包装在另一个函数中,放入类中,甚至在最后返回结果。该函数不会改变任何未显式传递给它的变量。换句话说,在这段代码中,虽然res是全局的,但它并不需要是全局的。我没有这样做是为了保持对函数本身的关注。 - user1984
同意,但那样你就不能回答问题了。 - duTr

2

你可以在递归中传递当前路径:

def allPaths(node,path=[]):
    if not node: return            # no node, do nothing
    fullPath = path + [node.value]
    if node.left or node.right:    # node is not a leaf, recurse down      
        yield from allPaths(node.left, fullPath)    # left leaves if any
        yield from allPaths(node.right, fullPath)   # right leaves if any
    else:
        yield fullPath             # leaf node, return final path

2
我提供另一种选择。
def allPaths(root, path=[]):
    tmp = []
    if root.left:
        tmp.extend(allPaths(root.left, path + [root.value]))
    if root.right:
        tmp.extend(allPaths(root.right, path + [root.value]))
    if not root.left and not root.right:
        tmp.append(path + [root.value])
    return tmp


tree = allPaths(root)
print(tree)

输出结果为:
[[1, 2, 4], [1, 2, 5], [1, 3, 6]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接