Trees
描述树形结构的术语
递归描述 - 一课树有一个根节点和一系列分支节点 - 每个分支也是一棵树,也有根节点与分支节点 - 没有分支节点的树被称为叶子节点
亲戚描述
- 树的每个位置被称为节点
- 每个节点可以表示任何值
- 一个节点可以称为另一个节点的父节点/子节点

实现树形结构的抽象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def tree(label, branches=[]):
for branch in branches:
assert is_tree(branch), "branches must be trees" # 确保构造的是一棵树
return [label] +list(branches) # 将同一层的分支节点放在一个列表中
def label(tree):
return tree[0]
def branches(tree):
return tree[1:]
def is_tree(tree):
"""判断是不是一棵树"""
if type(tree) != list or len(tree) <1: # 确保树的分支是树,以及存在一个值
return False
for branch in branches(tree): # 确保树的分支的分支都是树
if not is_tree(branch):
return False
return True
def is_leaf(tree):
"""判断树本身是不是叶子节点"""
return not branches(tree)
if __name__ == "__main__":
t = tree(1, [tree(5, [tree(7)]), tree(6)])
print(t)
print(label(t))
print(branches(t))
print(label(branches(t)[0]))[1, [5, [7]], [6]]
1
[[5, [7]], [6]]
5
Tree Processing
处理叶子节点
使用递归,将会在每个分支节点进行递归调用,最后合并
1
2
3
4
5
6
7
8
9
10
def count_leaves(t):
"""Count the leaves of tree T"""
if is_leaf(t):
return 1
else:
return sum([count_leaves(b) for b in branches(t)])
if __name__ == "__main__":
t = tree(1, [tree(5, [tree(7)]), tree(6)])
print(count_leaves(t))2
返回叶子节点的值
实现leaves函数,返回树的叶子节点的值的列表
1
2
3
4
5
6
7
8
9
10
def leaves(tree):
"""return a list containing the leaf labels of tree"""
if is_leaf(tree):
return [label(tree)]
else:
return sum([leaves(b) for b in branches(tree)], [])
if __name__ == "__main__":
t = tree(1, [tree(5, [tree(7)]), tree(6)])
print(leaves(t))[7, 6]
根据树创建树
使用递归根据另一棵树创建一颗新树 如让叶子节点值+1的树 或让所有节点都+1的树
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def increment_leaves(t):
"""return a tree like t but with leaf labels incremented"""
if is_leaf(t):
return tree(label(t)+1)
else:
bs = [increment_leaves(b) for b in branches(t)]
return tree(label(t), bs)
def increment(t):
"""return a tree like t but with all labels incremented"""
return tree(label(t)+1, [increment(b) for b in branches(t)])
if __name__ == "__main__":
t = tree(1, [tree(5, [tree(7)]), tree(6)])
print(leaves(t))
print(increment_leaves(t))
print(increment(t))[7, 6]
[1, [5, [8]], [7]]
[2, [6, [8]], [7]]
例:print_tree
按节点在树中的深度缩进打印一颗树
1
2
3
4
5
6
7
8
def print_tree(t, indent = 0):
print(' '*indent + str(label(t)))
for b in branches(t):
print_tree(b, indent+1)
if __name__ == "__main__":
t = tree(1, [tree(5, [tree(7)]), tree(6)])
print(print_tree(t))1
5
7
6
None
例: 求从根节点沿路径到叶子节点求和并打印
1
2
3
4
5
6
7
8
9
10
11
def print_sums(t, so_far):
so_far = so_far +label(t)
if is_leaf(t):
print(so_far)
else:
for b in branches(t):
print_sums(b,so_far)
if __name__ == "__main__":
t = tree(1, [tree(5, [tree(7)]), tree(6)])
print(print_sums(t, 0))13
7
None