Download presentation
Presentation is loading. Please wait.
1
04 Trees Part I CS 310 photo ©Oregon Scenics used with permissionOregon Scenics All figures labeled with “Figure X.Y” Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
2
2 Trees A tree is either empty or consists of a root and zero or more nonempty subtrees.
3
3 Tree anatomy
4
4
5
5
6
6
7
7
8
8
9
9 First child/next sibling implementation
10
10 Preorder tree traversal visit tree(node) { if (node == null) return else { print node for (c in children) visit tree(c) } root B E J K F G C H I D What’s the complexity?
11
11 Postorder tree traversal visit tree(node) { if (node == null) return else { for (c in children) visit tree(c) } print node } J K E F … ? Why would we care whether we use preorder or postorder traversal?
12
12 Recursion Recursive methods make calls to themselves –directly –indirectly Why bother with recursion? –Frequently leads to elegant code –Language’s runtime system does much of the work for us (we’ll see this later)
13
13 An example Each time we call a subroutine, an activation record is pushed onto the stack.
14
14 An example
15
15 An example
16
16 An example How could we have implemented this iteratively?
17
17 How to prove by induction Start by proving a basis –Show it for the easy case first Make an inductive hypothesis –Assume that what you are trying to prove holds true for an arbitrary base case –Consider what happens for the next case –Typically, we show that if the base case holds, than the next one must hold as well.
18
18 Example, Theorem 7.2
19
19 Basis
20
20 Inductive hypothesis
21
21 Induction step
22
22 Induction step
23
23 Induction step
24
24 Your turn…
25
25 binary trees A binary tree is a tree that has exactly 0, 1, or 2 subtrees. We name the subtrees the left and right subtrees. One application of binary trees: expression trees
26
26 operations on a binary tree traversals (may be implemented by iterators) size() – Number of nodes in tree height() – Height of tree isEmpty() – Any nodes in tree? makeEmpty() – remove all nodes merge(root, leftSubtree, rightSubtree)
27
27 Implementation decisions Where should we put the functionality? –tree object? –node object? Should the node be a nested class?
28
28 BinaryTree skeleton
29
29 BinaryNode skeleton
30
30 Merging trees Desired semantics of t.merge(item, leftSubTree, rightSubtree):
31
31 Naïve merge We might be tempted to write merge: public void merge(T newRoot, BinaryTree left, BinaryTree right) { // Set the root node to a new node, effectively deleting whatever // we had before. Make left & right the children. root = new BinaryNode (newRoot, left.root, right.root); } Note: T substituted for AnyType due to space constraints.
32
32 Trouble in paradise… t.merge(x, t1, t2) Suppose we had an alias to either t1 or t2 before the merge, what happens if we modify these now? break binding old tree
33
33 Is this any better? public void merge(T newRoot, BinaryTree left, BinaryTree right) { // Set the root node to a new node, effectively deleting whatever // we had before. Make left & right the children. root = new BinaryNode (newRoot, left.root, right.root); // avoid aliasing by making the merge destructive left.root = null; right.root = null; } Consider: t1.merge(x, t1, t2)
34
34 Another case to consider What about: t1.merge(x, t3, t3); Should we allow this? What are our options for allowing/disallowing?
35
35
36
36 Recursion with trees Note that here we do this with a method which operates on an object.
37
37 An example of doing this with a static method. Note how we terminate the recursion.
38
38
39
39 pre/in/post-order traversal
40
40 Iterators Your text shows that we can create iterators by using a stack 18.4.1 – 18.4.3. Read these on your own. The key concept is that in some traversals we need to visit an item multiple times.
41
41 Iterators As an example, the postorder iterator has to visit a node three times: 1.before visiting the left subtree 2.before visiting the right subtree 3.ready to process the current node When written recursively, this is simple When written iteratively, we have to do extra bookkeeping.
42
42 Iterators Your text solves the problem by pusing a class onto the stack that remembers both the node and the number of times it has been visited. By looking at the number of times it has been visited, we can determine which state we are in.
43
43 Level order traversal This is a little bit trickier… desired output: root, B, C, D, E, F, G, H, I, J, K How do we do this?
44
44
45
45
46
46
47
47 binary search trees Up to now, tree access O(N) When N large, too expensive Binary search trees –average case: O(log N) –worst case: O(N) Later, we will see ways to eliminate the linear worst case
48
48 Ordering property Binary trees must select a key (value) on which to order. Binary search tree order property For any node n in the tree All nodes l in the left subtree have key(l)<key(n) All nodes r in the right subtree have key(r)>key(n) Duplicates? Keep a count or disallow.
49
49 Operations find – easy insert – pretty easy remove – more difficult Other operations –findMin, findMax –isEmpty, makeEmpty
50
50
51
51
52
52
53
53
54
54 insertion into empty tree special case into nonempty tree –determine which subtree –insert into appropriate subtree
55
55 insert
56
56 remove # children 0 – easy 1 – move child up 2 – replace node with smallest child in right subtree (left most node in right subtree)
57
57 finding the smallest child removeMin(t.right) t points here
58
58
59
59 Complexity analysis insertion & find –worst case: What do you think? –average case: We need to search to the leaves of the tree. If we know the average path length, we can figure out how many nodes we can have a measure of this. Recall: path length is the number of edges between the root and a node.
60
60 Path length Internal path length: Sum of the depths of a tree’s nodes
61
61 Path length External path length: Sum of the depths of the null links (treating them as external nodes) Thm 19.2: The external path length for any tree is the internal path length + the number of external nodes. Thm: Any tree with N nodes has N+1 external links.
62
62 A successful find When we find a node, we have traveled down one of the paths of the tree. So, the average case –travels the length of an average path –plus one additional node to account for the node itself. If we can determine the internal path length, we can divide by the number of paths (one for each node) to get the average path length.
63
63
64
64
65
65
66
66 Average successful find Since the average internal path length is of order O(N log N) and there are N paths, each path is on average of length A sucessful find will thus visit log(N) + 1 nodes and is of order O(log N).
67
67 Average unsuccessful find or insertion When we are unable to find a node or want to insert, we will eventually visit one of the N+1 null links. The average number of links we visit is: so this is also O(N log N)
68
68 Average case insertion/find We assumed that the tree was built with a randomly ordered sequence. Given our strategy of always deleting the leftmost child in the right subtree, will deletions cause skew in the tree? –In practice this is not too bad. –However, we will learn later about methods to keep the tree balanced.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.