【问题标题】:Get all branches(root to leaf) of a binary tree as lists in Python获取二叉树的所有分支(从根到叶)作为 Python 中的列表
【发布时间】:2019-07-08 06:02:36
【问题描述】:

我在 Python 中以字典的形式创建了一个二叉树,其中每个条目的格式为 key: value。例如,

btree = {..., 
         node1: [value, nodeNoOfLeftChild, nodeNoOfRightChild],
         ... }

所有节点都具有相同格式的条目,但也可能缺少一些节点。

例如,如果节点号 5 的值为 X,子节点号是 12 和 13,则条目看起来像。

tree[5] = [X, 12, 13]

但可能节点 13 不存在,因此节点 5 只有一个子节点。 也有可能节点 12 和 13 都不存在,这使得节点 5 成为叶节点。

我想将树的所有分支(从根到叶)作为列表获取,但问题是列表长度因分支而异。

我如何创建一个函数来接收这本字典并给出列表?

【问题讨论】:

  • 您只获得了 3 个节点的示例。如果有超过 2 个级别怎么办?您可能还想查看 BST 的预购遍历。
  • 我已经举例说明了我是如何存储树的每个节点的。
  • 子节点及其子节点等会有类似的条目
  • 给定节点 5 没有任何子节点,那么它在二叉树中的列表是否真的有其他条目而不是它的值?
  • 通常不使用映射来创建二叉树。相反,您使用一个固定的结构,通常是一个 Node 类来执行此操作。您可以使用一个简单的数组,就像您展示的那样,但没有理由将节点放在地图中。相反,您的子条目应该只是对其他节点的引用,或者如果特定插槽中没有子节点,则为 None。 - 你在说什么会起作用。您只需要很好地定义如何解释地图中的数组中可能包含哪些值。

标签: python binary-tree traversal


【解决方案1】:

这是一个使用您的数据结构并生成每个叶节点的路径的示例。为了让它变得有趣,我选择让路径由节点的名称组成。路径可以很容易地成为节点编号。我不确定为什么子节点会有一个数字但不存在,所以我的示例假设如果子节点条目非零,则该节点存在:

from pprint import pprint

btree = {
    1: ["Node 1", 2, 3],
    2: ["Node 2", 4, 0],
    3: ["Node 3", 0, 0],
    4: ["Node 4", 5, 0],
    5: ["Node 5", 6, 0],
    6: ["Node 6", 7, 0],
    7: ["Node 7", 0, 0],
}

def do_node(id, path, result):
    node = btree[id]
    if node[1] == 0 and node[2] == 0:
        # This node has no children, and is thus a leaf node, so add it to the result list
        result.append(path + [node[0]])
    else:
        # This is a non-leaf node, so process its children
        if node[1] != 0:
            do_node(node[1], path + [node[0]], result)
        if node[2] != 0:
            do_node(node[2], path + [node[0]], result)


def print_leaf_paths(tree):
    result = []
    do_node(1, [], result)
    pprint(result)

print_leaf_paths(btree)

示例树有两个叶子节点,一个立即和一个向下 5 级。结果是:

[['Node 1', 'Node 2', 'Node 4', 'Node 5', 'Node 6', 'Node 7'],
 ['Node 1', 'Node 3']]

【讨论】:

    【解决方案2】:

    这是一个使用您的数据结构并生成每个叶节点的路径的示例。为了让它变得有趣,我选择让路径由节点的名称组成。路径可以很容易地成为节点编号。我不确定为什么子节点会有一个数字但不存在,所以我的示例假设如果子节点条目非零,则该节点存在:

    from pprint import pprint
    
    btree = {
        1: ["Node 1", 2, 3],
        2: ["Node 2", 4, 0],
        3: ["Node 3", 0, 0],
        4: ["Node 4", 5, 0],
        5: ["Node 5", 6, 0],
        6: ["Node 6", 7, 0],
        7: ["Node 7", 0, 0],
    }
    
    # Process a single node in a binary tree
    def do_node(id, path, result):
        node = btree[id]
        if node[1] == 0 and node[2] == 0:
            # No children, so this is a leaf node.  Add it to the result list
            result.append(path + [node[0]])
        else:
            # Non-leaf node, so process the node's children recursively.
            if node[1] != 0:
                do_node(node[1], path + [node[0]], result)
            if node[2] != 0:
                do_node(node[2], path + [node[0]], result)
    
    
    # Build a list of "paths" to each of the leaf nodes in a binary tree
    def print_leaf_paths(tree):
        result = []
        do_node(1, [], result)
        pprint(result)
    
    print_leaf_paths(btree)
    

    示例树有两个叶节点,一个在根的正下方,一个在 5 层以下。结果是:

    [['Node 1', 'Node 2', 'Node 4', 'Node 5', 'Node 6', 'Node 7'],
     ['Node 1', 'Node 3']]
    

    【讨论】:

      【解决方案3】:

      您可以将递归与生成器一起使用:

      tree = {1: ['Node 1', 2, 3], 2: ['Node 2', 4, 0], 3: ['Node 3', 0, 0], 4: ['Node 4', 5, 0], 5: ['Node 5', 6, 0], 6: ['Node 6', 7, 0], 7: ['Node 7', 0, 0]}
      def paths(a, c = []):
        if a not in tree:
          yield tuple(c)
        else:
          for i in tree[a][1:]:
            yield from paths(i, c+[tree[a][0]])
      
      print(list(set(paths(1))))
      

      输出:

      [('Node 1', 'Node 2', 'Node 4', 'Node 5', 'Node 6'), ('Node 1', 'Node 2'), ('Node 1', 'Node 2', 'Node 4'), ('Node 1', 'Node 3'), ('Node 1', 'Node 2', 'Node 4', 'Node 5'), ('Node 1', 'Node 2', 'Node 4', 'Node 5', 'Node 6', 'Node 7')]
      

      【讨论】:

        猜你喜欢
        • 2019-08-20
        • 1970-01-01
        • 1970-01-01
        • 2021-04-21
        • 1970-01-01
        • 2015-06-14
        • 1970-01-01
        • 1970-01-01
        • 2021-09-29
        相关资源
        最近更新 更多