获取二叉树的所有分支(从根到叶)作为Python中的列表

时间:2019-07-08 06:02:36

标签: python binary-tree traversal

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

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

所有节点的条目格式相同,但是某些节点也可能丢失。

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

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

但是节点13可能不存在,所以节点5只有一个孩子。 节点12和13都可能不存在,这使得节点5成为叶节点。

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

我如何制作一个可以接收此词典并给出列表的函数?

3 个答案:

答案 0 :(得分: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']]

答案 1 :(得分:0)

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

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']]

答案 2 :(得分:0)

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

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')]