04 trees part i cs 310 photo ©oregon scenics used with permissionoregon scenics all figures labeled...

Post on 15-Jan-2016

215 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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.

top related