04 trees part i cs 310 photo ©oregon scenics used with permissionoregon scenics all figures labeled...
Post on 15-Jan-2016
215 views
TRANSCRIPT
04 TreesPart I
CS 310
photo ©Oregon Scenics used with permission
All figures labeled with “Figure X.Y”
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
2
Trees
• A tree is either empty or consists of a root and zero or more nonempty subtrees.
root
othersubtrees
...
othersubtrees
othersubtrees
3
Tree anatomy
root
B
G HE F I
C D
KJ
Node – where information is stored
– directed edges join nodes
4
Tree anatomy
root
B
G HE F I
C D
KJ Parent/child relationships
parent
child
ance
stor
s
desc
ende
nts
5
Tree anatomy
root
B
G HE F I
C D
KJ
ance
stor
s
desc
ende
nts
A node is an ancestor/descendent of itself, but not a proper ancestor/
descendent
6
Tree anatomy
root
B
G HE F I
C D
KJ
Nodes with the same parents are called siblings.
7
Tree anatomy
root
B
G HE F I
C D
KJPath – a unique set of edges from
one node to another
Rootà Bà Eà K is a path of length 3
8
Tree anatomy
root
B D
dept
h
0
1
2
3
height(B)=2
height(D)=0
9
First child/next sibling implementation
root
B
G HE F I
C D
KJ
NODE
Child Pointer
Sibling Pointer
10
Preorder tree traversal
visit tree(node) {if (node == null)
returnelse {
print node for (c in children)
visit tree(c)}
}
root
B
G HE F I
C D
KJ
root B E J K F G C H I D
What’s the complexity?
11
Postorder tree traversal
visit tree(node) {if (node == null)
returnelse {
for (c in children)visit tree(c)
}print node
}
root
B
G HE F I
C D
KJ
J K E F … ?
Why would we care whether we usepreorder or postorder traversal?
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
An example
n = 273base = 10
273/10 = 27
top of stack
printInt(273, 10) Each time we call a subroutine,an activation record is pushed onto the stack.
14
An example
n = 273base = 10
27/10 = 2
top of stack
printInt(273, 10)
n = 27base = 10
printInt(27, 10)
15
An example
n = 273base = 10
2 < 10 no recursion, 2 % 10 = 2
top of stack
printInt(273, 10)
n = 27base = 10
printInt(27, 10)
n = 2base = 10
printInt(2, 10)
Output: “2”
16
An example
n = 273base = 10
top of stack
printInt(273, 10)
n = 27base = 10
printInt(27, 10)
27 % 10 = 7 Output: “27”
n = 273base = 10
top of stack
printInt(273, 10)
273 % 10 = 3 Output: “273”
How could we have implemented this iteratively?
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
Example, Theorem 7.2
2221 2
1 2
)2()1( )1( Note
2
)1()1( Prove
NNNi
NNi
Ni
iN
Ni
iN
19
Basis
basis for the trueis thisso
12
)11(1
2
)1(
as same theis but this
1
1)1(
)1(
1NLet
211
1
1
21
NN
ii
i
20
Inductive hypothesis
1kkfor trueisit that show tohave weNow
2
)1()1(
k somefor holds theorem that theAssume
1 2
kki
ki
ik
21
Induction step
2221 2
22221
1
21
1
1
2)1(
)2()1()( )1(
k.for expect would what welikelook thisofpart make try to weNow
)2()1()()1( )1(
sum... theexpandingby start usLet
2
)2)(1(
2
)1)1)((1()1(
show
kkki
kkkki
kkkki
ki
ik
ki
ik
ki
ik
22
Induction step
2
)2)(1(2
23
2
242
2
)1()1(
)2()1()()1(
)2()1()()1( )1(
2
22
2
2222
almost...
22221
1
21
kk
kk
kkkk
kkk
kkkk
kkkkiki
ik
23
Induction step
1 allfor trueis that thisinduction by shown have we
,2
)2)(1( )1( As
1
1
21
N
kki
ki
ik
24
Your turn…
induction.by 2
)1(21 Prove
1
NNNi
N
i
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
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
Implementation decisions
• Where should we put the functionality?– tree object?– node object?
• Should the node be a nested class?
28
BinaryTreeskeleton
29
BinaryNodeskeleton
30
Merging trees
• Desired semantics of
t.merge(item, leftSubTree, rightSubtree):
31
Naïve merge
• We might be tempted to write merge:
public void merge(T newRoot, BinaryTree<T> left, BinaryTree<T> right) {
// Set the root node to a new node, effectively deleting whatever
// we had before. Make left & right the children.
root = new BinaryNode<T>(newRoot, left.root, right.root);
}
Note: T substituted for AnyType due to space constraints.
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
oldtree
33
Is this any better?
public void merge(T newRoot, BinaryTree<T> left, BinaryTree<R> right) {// Set the root node to a new node, effectively deleting whatever// we had before. Make left & right the children.root = new BinaryNode<T>(newRoot, left.root, right.root);// avoid aliasing by making the merge destructiveleft.root = null;right.root = null;
}Consider: t1.merge(x, t1, t2)
34
Another case to consider
• What about: t1.merge(x, t3, t3);
• Should we allow this?
• What are our options for allowing/disallowing?
35
36
Recursion with trees
Note that here we do this with a methodwhich operates on an object.
37An example of doing this with a static method.Note how we terminate the recursion.
38
39
pre/in/post-order traversal
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
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
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
Level order traversal
• This is a little bit trickier… root
B
G HE F I
C D
KJ
desired output:root, B, C, D, E, F, G, H, I, J, KHow do we do this?
44
45
46
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
Ordering property
• Binary trees must select a key (value) on which to order.
• Binary search tree order propertyFor 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
Operations
• find – easy
• insert – pretty easy
• remove – more difficult
• Other operations– findMin, findMax– isEmpty, makeEmpty
50
51
52
53
54
insertion
• into empty tree special case
• into nonempty tree– determine which subtree– insert into appropriate subtree
55
insert
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
finding the smallest child
removeMin(t.right)t points here
58
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
Path length
• Internal path length: Sum of the depths of a tree’s nodes
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
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
64
65
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).
)(loglog
NON
NNO
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)
nodes externalnumber
lengthpath external
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.