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

以Python中的列表形式获取二叉树的所有分支(从根到叶),python,binary-tree,traversal,Python,Binary Tree,Traversal,我用Python制作了一个字典形式的二叉树,其中每个条目的形式都是key:value。比如说, btree = {..., node1: [value, nodeNoOfLeftChild, nodeNoOfRightChild], ... } 所有节点都具有相同格式的条目,但也可能缺少某些节点 例如,如果节点编号5的值为X,子节点编号为12和13,则条目如下所示 树[5]=[X,12,13] 但是节点13可能不存在,所以节点5只有一个子节点。 节点12和

我用Python制作了一个字典形式的二叉树,其中每个条目的形式都是
key:value
。比如说,

btree = {..., 
         node1: [value, nodeNoOfLeftChild, nodeNoOfRightChild],
         ... }
所有节点都具有相同格式的条目,但也可能缺少某些节点

例如,如果节点编号5的值为X,子节点编号为12和13,则条目如下所示

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

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

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


如何创建一个函数,该函数接受此字典并给出列表?

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

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)
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']]
[['Node 1', 'Node 2', 'Node 4', 'Node 5', 'Node 6', 'Node 7'],
 ['Node 1', 'Node 3']]

下面是一个使用数据结构并生成每个叶节点路径的示例。为了使其有趣,我选择了由节点名称组成的路径。路径也可以是节点编号。我不确定为什么子节点会有一个数字但不存在,因此我的示例假设如果子节点条目为非零,则该节点存在:

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)
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']]
[['Node 1', 'Node 2', 'Node 4', 'Node 5', 'Node 6', 'Node 7'],
 ['Node 1', 'Node 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')]

仅给出了3个节点的示例。如果有两个以上的级别怎么办?您可能还想了解BST的预顺序遍历。我已经给出了如何存储树的每个节点的示例。子节点将有类似的条目,它们的子节点,因此onGiven节点5没有任何子节点,那么它在二叉树中的列表是否真的除了它的值之外还有其他条目呢?人们通常不使用映射来创建二叉树。相反,您可以使用一个固定的结构(通常是一个节点类)来实现这一点。您可以使用如图所示的简单数组,但没有理由将节点放在地图中。相反,您的子条目应该只是对其他节点的引用,如果特定插槽中没有子节点,则应该是无引用。-不过你所说的会管用的。您只需定义好如何解释映射中数组中可能存在的值。