14 Trees 4pp
14 Trees 4pp
Tree Abstraction
Root of the whole tree or Root Node
Nodes
Root label 3
Labels
Root of a branch
Branch 1 2
(also a tree)
0 1 1 1
Trees
Leaf
0 1
(also a tree) Path
People often refer to labels by their locations: "each parent is the sum of its children"
4
Implementing the Tree Abstraction Implementing the Tree Abstraction
def tree(label, branches=[]): • A tree has a root label def tree(label, branches=[]): • A tree has a root label
return [label] + branches for branch in branches: Verifies the
and a list of branches and a list of branches
tree definition
• Each branch is a tree assert is_tree(branch) • Each branch is a tree
def label(tree): return [label] + list(branches)
return tree[0]
3 def label(tree): Creates a list 3
def branches(tree): return tree[0] from a sequence
of branches
return tree[1:]
1 2 def branches(tree): 1 2
Verifies that
return tree[1:]
1 1 tree is bound 1 1
to a list
def is_tree(tree):
>>> tree(3, [tree(1), >>> tree(3, [tree(1),
... tree(2, [tree(1), if type(tree) != list or len(tree) < 1: ... tree(2, [tree(1),
... tree(1)])]) return False ... tree(1)])])
[3, [1], [2, [1], [1]]] for branch in branches(tree): [3, [1], [2, [1], [1]]]
if not is_tree(branch):
def is_leaf(tree):
return False
return not branches(tree) (Demo)
return True
5 6
The recursive case typically makes a recursive call on each branch, then aggregates
def count_leaves(t):
Tree Processing """Count the leaves of a tree."""
if is_leaf(t):
return 1
else:
branch_counts = [count_leaves(b) for b in branches(t)]
return sum(branch_counts)
(Demo)
(Demo)
8
Discussion Question Creating Trees
Implement leaves, which returns a list of the leaf labels of a tree A function that creates a tree from another tree is typically also recursive
Hint: If you sum a list of lists, you get a list containing the elements of those lists
>>> sum([ [1], [2, 3], [4] ], []) def leaves(tree): def increment_leaves(t):
[1, 2, 3, 4] """Return a list containing the leaf labels of tree. """Return a tree like t but with leaf labels incremented."""
>>> sum([ [1] ], []) if is_leaf(t):
[1] >>> leaves(fib_tree(5)) return tree(label(t) + 1)
>>> sum([ [[1]], [2] ], []) [1, 0, 1, 0, 1, 1, 0, 1] else:
[[1], 2] """ bs = [increment_leaves(b) for b in branches(t)]
if is_leaf(tree):
return tree(label(t), bs)
return [label(tree)]
else:
List of leaf labels for each branch
return sum(______________________________, [])
9 10
(Demo) (Demo)
Count Paths that have a Total Label Sum
def count_paths(t, total):
"""Return the number of paths from the root to any node in tree t
for which the labels along the path sum to total.
1
found = ________________ 1
else:
found = 0
________________________