如何只用一行遍历一棵树? (Python,树遍历)

问题描述 投票:0回答:3

对于二叉树,我们可以像这样一行遍历(中序、前序、后序都可以):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

# this is a preorder traversal with one line:

class Solution:
    def preorderTraversal(self, root) -> List[int]:
        return [] if root is None else [r.val] + self.preorderTraversal(r.left) + self.preorderTraversal(r.right)

对于一棵节点有多个子节点的树,如何一行完成遍历工作? 我认为列表理解是一种可能的方法,但我无法一行完成这项工作。

"""
# Definition for a Node.
class Node:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""
class Solution:
    def preorder(self, root: 'Node') -> List[int]:
        if root is None: return []
        ans = [root.val]
        [ans.extend(x) for x in [self.preorder(child) for child in root.children]]
        return ans

# This is a normal traversal:
# class Solution:
#     def preorder(self, root: 'Node') -> List[int]:
#         if root is None: return []
#         ans = [root.val]
#         for child in root.children:
#             ans += self.preorder(child)
#         return ans
python algorithm tree-traversal
3个回答
1
投票

使用列表理解来收集根的所有子节点的遍历,无论有多少个子节点。

class Solution:
    def preorderTraversal(self, root) -> List[int]:
        # Original hard-coded approach for binary trees
        # return [] if root is None else [r.val] \
        #   + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)

        # Generalized approach for binary trees
        # return [] if root is None else [r.val] \
        #   + [y for child in [root.left, root.right] for y in self.preorderTraversal(child)]

        # Generalized approach for a tree with arbitrary children per node
        return [] if root is None else ([root.val]
          + [y for child in root.children for y in self.preorderTraversal(child)])

0
投票

它可以像这样工作:

class Solution:
    def preorder(self, root):
        return [] if root is None else [root.val] + [value 
            for child in (root.children or []) 
                for value in self.preorder(child)]

这个想法是列表理解取代了对

append
的重复调用,而不是
extend
。映射到上述列表理解版本的非理解代码是:

class Solution:
    def preorder(self, root):
        if root is None:
            return []
        res = [root.val]
        for child in (root.children or []):
            for value in self.preorder(child):
                res.append(value)
        return res

0
投票

有一个智能Python oneliner,用于基于生成器的递归树中序遍历,首先发布于here

def inorderTr(r):
    yield from chain(inorderTr(r.left), (r.val,), inorderTr(r.right)) if r else ()
© www.soinside.com 2019 - 2024. All rights reserved.