39
17 - 1 Binary Trees PS4 due 1:30pm Tuesday, April 10 Wellesley College CS230 Lecture 17 Thursday, April 5 Handout #28

17 - 1 Binary Trees PS4 due 1:30pm Tuesday, April 10 Wellesley College CS230 Lecture 17 Thursday, April 5 Handout #28

Embed Size (px)

Citation preview

17 - 1

Binary Trees

PS4 due 1:30pm Tuesday, April 10

Wellesley College CS230 Lecture 17

Thursday, April 5Handout #28

17 - 2

Motivation: Inefficiency of Linear Structures

Up to this point our focus has been linear structures: arrays, vectors, linked lists

Some operations on linear structures are cheap: • Constant time:

Get/set elt at a given index in array/vector Add elt to the end of a vectorAdd elt to the front of a im/mutable listAdd elt to the back of a mutable list (if have pointer to last node)

• Logarithmic time: Binary search on sorted array/vector

Other operations are expensive (linear in size): Inserting/deleting elt at arbitrary position in an array/vector/listFinding an element in a list (even a sorted one)

There is no linear structure for which insertion, deletion, and membership operations (e.g. in priority queues, sets, bags, and tables) are all cheaper than linear.

17 - 3

Idea: Branching of Binary Search + Linking of Linked Lists → Binary Trees

A binary tree is either

• a leaf:

• a node with (1) a left subtree (2) a value and (3) a right subtree:

binary tree node

left subtree right subtreevalue

17 - 4

A Sample Binary Tree

F

C

G

A

D B

E

F

C

G

A

D B

E

Values are often shown in the nodes

Often, the leaves are not shown, but they’re still there!

17 - 5

Tree Terminology

F

C

G

A

D B

E

Nodes A and C are the children of node F; F is the parent of A and C; A and C are siblings. Grandparents, grandchildren, etc. defined similarly.

A node without a parent is a root. E.g. node F is the root of the tree, and node A is the root of F’s left subtree (considered separately from the whole tree).

A descendant of a node n is a node on the path from n to a leaf. E.g. nodes D, B, and E are the descendants of A.

An ancestor of a node n is a node on the path from n to the root. E.g. Nodes B, A, and F are the ancestors of E.

17 - 6

More Tree Terminology

F

C

G

A

D B

E

The height of a node n is length of the longest path from n to a leaf below it. E.g., node G has height 1, node C has height 2, and node F has height 4.

The depth of a node n is the length of the path from n to the root. E.g., node F has depth 0, node C has depth 1, and node G has depth 2.

A binary tree is height-balanced iff at every node n, the heights of n’s left and right subtrees differ by no more than 1. The example tree is height-balanced, but would not be if G were removed. (There are other notions of tree balance in CS231.)

17 - 7

Binary Search Trees

E

F

G

B

A D

C

To get full advantage of binary trees for data structures, need the values to be ordered.

A binary search tree (BST) is a binary tree in which the following properties hold at every node: (1) All elements in the left subtree are ≤ the value; (2) All elements in the right subtree are ≥ the value.

Here is a sample BST →

BSTs will be very important in the next lecture, when we use binary trees to implement data structureslike sets, bags, and tables For now,we’ll stick with generic binary trees.

17 - 8

Trees: An Omnipresent Data Representation

• Family trees• File system• Sport tournaments• Animal kingdom• Organizational chart• Java class hierarchy• A graph without cycles• A home’s plumbing and

electrical systems • …• A convenient data

structure

A tree T is a set of one or more nodes s.t.

T is partitioned into two disjoint subsets:• A single node r, the root• Sets that are also trees, called subtrees of r

17 - 9

The Binary Tree

17 - 10

Arithmetic Expressions as Trees

Arithmetic expressions are often represented as binary trees.

Internal nodes are operations - Leaves are numbers/variables.

Operator precedence is enforced by the tree shape.

-

a b

-

a

c

/

b a b

*

- c

a-b a-(b/c) (a-b)*c

17 - 11

TreeInterface

public interface TreeInterface { public boolean isLeaf ();

public Object getValue ();

public Tree getLeft ();

public Tree getRight ();

public void setValue (Object newValue);

public void setLeft (Tree newLeft);

public void setRight (Tree newRight);

public String toString ();}

17 - 12

Example

public static void main(String[] args) {Tree T = new Tree();T = new Tree("A",

new Tree(), new Tree());Tree tl = new Tree("B",

new Tree(), new Tree());Tree tr = new Tree("C",

new Tree(), new Tree());T.setLeft(tl);T.setRight(tr);T.getLeft().setValue(new Integer(5));

T.setRight(T.getRight().getRight());

}

• Draw T’s contents

.

(. A .)

((. B .) A (. C .))

((. 5 .) A (. C .))

((. 5 .) A .)

17 - 13

Tree Implementation Contract

public Tree ()

public Tree (Object val, Tree lt, Tree rt)

public boolean isLeaf ()

public Object getValue ()

public Tree getLeft ()

public Tree getRight ()

public void setValue (Object newValue)

public void setLeft (Tree newLeft)

public void setRight (Tree newRight)

public String toString ()

lt value isLeaf rt private Object value; private Tree lt, rt; private boolean isLeaf;

“Jane” F

“Sally” F

/ “” T /

“Joe” F

/ “” T / / “” T // “” T /

17 - 14

public class Tree implements TreeInterface {

// instance variables private Object value; private Tree left, right; private boolean isLeaf;

// constructors public Tree () { isLeaf = true; }

public Tree (Object value, Tree lt, Tree rt) {

this.value = value; this.left = lt; this.right = rt; isLeaf = false; } // instance methods public boolean isLeaf () { // returns true if the tree is a

leaf (i.e. empty tree) return isLeaf; }

public Object getValue () { if (isLeaf) throw new RuntimeException ("Attempt to

get value of empty tree"); else return value;}

public Tree getLeft () { if (isLeaf) throw new RuntimeException ("Attempt to

get left subtree of an empty tree"); else return left; }

public Tree getRight () { if (isLeaf) throw new RuntimeException ("Attempt

to get right subtree of an empty tree"); else return right; }

17 - 15

And the Rest...

public void setValue (Object newValue){ // sets the Object in the root node of the tree to a new value if (isLeaf) throw

new RuntimeException ("Attempt to get value of empty tree"); else

this.value = newValue;}

public void setLeft (Tree newLeft) { // changes the left subtree to a new tree

}

public void setRight (Tree newRight){ // changes the right subtree to a new tree

}

17 - 16

How Do You Print a Tree?

public String toString () {// returns a String

representation of the contents of a Tree

}

10 +

*

/

5

-

3 2

17 - 17

Ways to Visit the Nodes of a Tree

public String toString () {// returns a String

representation of the contents of a Tree

if (this.isLeaf()) return ""; else return

"(" + this.getLeft().toString() + " " + this.getValue() + " " + this.getRight().toString() + ")";

}

10 +

*

/

5

-

3 2

17 - 18

Syntatic Sugar - a bunch of static’s

public static Tree leaf () {return new Tree();

}

public static Tree node (Object val, Tree lt, Tree rt) {

return new Tree(val, lt, rt);}

public static boolean isLeaf (Tree t) {return t.isLeaf;

} public static Object getValue(Tree t) {

return t.getValue();}

public static Tree getLeft(Tree t) {return t.getLeft();

}

public static Tree getRight(Tree t){return t.getRight();

}

public static void setValue (Tree t, Object newValue) {t.setValue(newValue);

}

public static void setLeft (Tree t, Tree newLeft) {t.setLeft(newLeft);

}

public static void setRight (Tree t, Tree newRight) {t.setRight(newRight);

}

// using the new notation:Tree T = leaf();T = node("A", leaf(), leaf());Tree tl = node("B", leaf(), leaf());Tree tr = node("C", leaf(), leaf());setLeft(T, tl);setRight(T, tr);setValue(getLeft(T),new Integer(5)); setRight(T, getRight(getRight(T)) );

17 - 19

Traversal of a Binary Tree

• Is a way of visiting each node in the tree• Recursive traversal algorithms

– Preorder traversal– Inorder traversal– Postorder traversal

3 4

1

2 7

5 6

1 4

6

2 7

3 5

1 4

7

5 6

2 3

17 - 20

Three Ways to Traverse the Tree

public static void preOrderWrite (Tree t) { // prints contents of the tree t using preOrder traversal of the nodes if (!isLeaf(t)) { System.out.print(" " + getValue(t)); preOrderWrite(getLeft(t)); preOrderWrite(getRight(t)); }}public static void inOrderWrite (Tree t) { // prints contents of the tree t using inOrder traversal of the nodes if (!isLeaf(t)) { inOrderWrite(getLeft(t)); System.out.print(" " + getValue(t)); inOrderWrite(getRight(t)); }}public static void postOrderWrite (Tree t) { // prints contents of the tree t using postOrder traversal of the nodes if (!isLeaf(t)) { postOrderWrite(getLeft(t)); postOrderWrite(getRight(t)); System.out.print(" " + getValue(t)); }}

17 - 21

Tree Contract (interface + instance vars)

public Tree ()

public Tree (Object val, Tree lt, Tree rt)

public boolean isLeaf ()

public Object getValue ()public void setValue (Object newValue)

public Tree getLeft ()public void setLeft (Tree newLeft)

public Tree getRight ()public void setRight (Tree newRight)

public String toString ()

lt value isLeaf rtprivate Tree lt;private Object value;private boolean isLeaf;private Tree rt;

“Jane” F

“Sally” F

/ “” T /

“Joe” F

/ “” T / / “” T // “” T /

17 - 22

Syntatic Sugar

public static Tree leaf () {return new Tree();

}public static Tree node (Object val, Tree lt, Tree rt) {

return new Tree(val, lt, rt);}

public static boolean isLeaf (Tree t) {return t.isLeaf;

} public static Object getValue(Tree t) {

return t.getValue();}

public static Tree getLeft(Tree t) {return t.getLeft();

}

public static Tree getRight(Tree t){return t.getRight();

}

public static void setValue (Tree t, Object newValue) {t.setValue(newValue);

}

public static void setLeft (Tree t, Tree newLeft) {t.setLeft(newLeft);

}

public static void setRight (Tree t, Tree newRight) {t.setRight(newRight);

}

Tree T = leaf();T = node("A", leaf(), leaf());Tree tl = node("B", leaf(), leaf());Tree tr = node("C", leaf(), leaf());setLeft(T, tl);setRight(T, tr);setValue(getLeft(T),new Integer(5)); setRight(T, getRight(getRight(T)) );

17 - 23

Basic Operations: height()

• Height of a node n is the distance from the node

to its furthest child

public static int height (Tree t){ // returns the height of the tree t if (isLeaf(t)) return 0; else return 1 + Math.max(

height(getLeft(t)), height(getRight(t)));

}

17 - 24

Basic Operations: countNodes()

public static int countNodes (Tree t) { // returns the number of nodes in tree t if ( ) else

}

17 - 25

Basic Operations: countOccurrences()

• Count occurrences of S in tree T – If root contains S, it is 1 +– The number of times it occurs in the left subtree +– The number of times it occurs in the right subtree

public static int countOccurrences (Tree t, String S) { // returns the number of nodes in the tree t that contain // the input String S if (isLeaf(t)) return 0; else { if (((String)getValue(t)).equals(S))

return 1 + countOccurrences(getLeft(t), S) +

countOccurrences(getRight(t), S); else

return countOccurrences(getLeft(t), S) + countOccurrences(getRight(t), S);

}}

A B

A

F

C

A

D A

17 - 26

Basic Operations: isMember()

isMember() returns true iff the input word is contained somewhere in the tree

public static boolean isMember (String word, Tree t) {if (isLeaf(t))

return false; else if (((String)t.getValue()).equals(word)) return true; else return(isMember(word, getLeft(t)) || isMember(word,getRight(t)));}

17 - 27

Full and Complete

• Full binary tree is a binary tree of height h with no missing nodes– All leaves are at level h – All internal nodes each have two

children

• Complete binary tree isa binary tree of height h that is full to level h – 1 and has level h filled in from left to right

• Full binary => complete• There is a simpler implementation

for full and complete trees

Helen

Wendy

Caitlin Joan Merideth

Nina

HelenWendy

CaitlinJoan

Merideth

Nina

01

3456

2

78

17 - 28

Recursive Definition of Full Binary Tree

• Full binary tree– If T is empty,

T is a full binary tree of height 0– Else if T is not empty

T is a full binary tree if its root’s subtrees are both full binary trees of height h – 1

public static boolean isFullBT (Tree t) {if

else

}

17 - 29

Array Representation of Binary Trees

A binary tree can be represented using an array of tree nodes

Each tree node contains a data portion and two indexes (one for each of the node’s children)

Requires the creation of a free list which keeps track of available nodes

The free list is being kept inside the tree array!

Allows for representation of any kind of tree, not just complete ones

item lt rtHelen 1 2

Wendy 3 4

Nina 5 -1

Caitlin -1 -1

Joan -1 -1

Merideth -1 -1

-1 7

-1 8

-1 9

… … …

0

1

2

3

4

5

6

7

8

0

6

tree root

free

Helen

Wendy

Caitlin Joan Merideth

Nina

17 - 30

Basic Operations: isBalanced()

A binary tree is balanced iff the height of any node’s right subtree differs by no more than 1from the height of the node’s left subtree

• Complete binary trees are balanced

public static boolean isBalanced(Tree t) { if (isLeaf(t)) return true; else return ((Math.abs(height(getLeft(t)) - height(getRight(t))) <= 1)

&& (isBalanced(getLeft(t))) && (isBalanced(getRight(t)))); }

17 - 31

Recording the Shape of a Tree

public static Tree makeStarTree (Tree t) { // returns a new tree that has

// the same size and shape as t, but with // all nodes in the tree containing

// a String with a * character if (isLeaf(t)) return leaf(); else return node ("*",

makeStarTree(getLeft(t)), makeStarTree(getRight(t)));

}

claire al

alex

joe

harry

bo

jane

* *

*

*

*

*

*

17 - 32

Applying a Function on a Tree

public static Tree makeReverseTree (Tree t) { // returns a new tree that is the same size // and shape as t, but with all of the // Strings labels in the tree reversed if (isLeaf(t)) return leaf(); else return node

(reverseString((String)getValue(t)),makeReverseTree(getLeft(t)), makeReverseTree(getRight(t)));

}

public static String reverseString (String S) { // returns a String that is the reverse of

the input String S String newS = ""; for (int i = 0; i < S.length(); i++) newS = S.charAt(i) + newS; return newS; }

claire al

alex

joe

harry

bo

jane

erialc la

xela

eoj

yrrah

ob

enaj

17 - 33

Destructive Versions

public static void makeStarTree2 (Tree t) { // alters the contents of the input tree so that all of the

// nodes contain a String with a star character if (!(isLeaf(t))) { setValue(t, "*"); makeStarTree2(getLeft(t)); makeStarTree2(getRight(t)); } }

public static void makeReverseTree2 (Tree t) { // alters the contents of the input tree so that all of the

// Strings in the tree are reversed if (!(isLeaf(t))) { setValue(t, reverseString((String)getValue(t))); makeReverseTree2(getLeft(t)); makeReverseTree2(getRight(t)); } }

17 - 34

The daVinci Tree ;-)

public static void flipTree (Tree t) { // alters the shape of tree // by changing it a mirror reversal if (!isLeaf(t)) { Tree tempTree = getLeft(t); setLeft(t, getRight(t)); setRight(t, tempTree); flipTree(getLeft(t)); flipTree(getRight(t)); } }

claire al

alex

joe

harry

bo

jane

harry al

alex

bo

claire

joe

jane

17 - 35

The Index of an Array Representation

public static Tree makeLabelTree (Tree t) { // returns a new tree with the same shape // and size as the input tree, // in which the value in each node // of the new tree is the index // of the node in an array representation return labelTree(t, 1);}

public static Tree labelTree (Tree t, int label) { // recursive helper method of makeLabelTree() if (isLeaf(t)) return leaf(); else return node(new Integer(label),

labelTree(getLeft(t), 2*label), labelTree(getRight(t), 2*label+1));

}

4 6

1

2

7

3

13

harry al

alex

bo

claire

joe

jane

17 - 36

makeHeightTree()

public static Tree makeHeightTree (Tree t) { /* returns a new tree that has the same size

and shape as t, and in which the node value is the height of the tree rooted at the corresponding node of the input tree */

if (isLeaf(t)) return leaf(); else return node(new Integer(height(t)),

makeHeightTree(getLeft(t)), makeHeightTree(getRight(t)));

}1 2

4

2

1

3

1

harry al

alex

bo

claire

joe

jane

17 - 37

makeLevelTree()

public static Tree makeLevelTree (Tree t) { /* returns a new tree that is the same size

and shape as t, in which the value in each node of the new tree is the level of the corresponding node in the input tree */

return levelTree(t, 0);}

public static Tree levelTree (Tree t, int h) {// recursive helper method for makeLevelTree() if (isLeaf(t)) return leaf(); else return node(new Integer(h + 1),

levelTree(getLeft(t), h + 1), levelTree(getRight(t), h + 1));

}

3 3

1

2

3

2

4

harry al

alex

bo

claire

joe

jane

17 - 38

Binary Search Tree (BST)

• A binary tree that for each node n:– n’s value is

greater than all values in its left subtree TL

– n’s value is less than all values in its right subtree TR

– Both TL and TR are binary search trees

A binary search tree of names

1 4

5

2

7

6

3

A binary search tree of numbers

Helen

Elaine

Caitlin Gina Merideth Wendy

Nina

17 - 39

Decision Trees for Expert Systems

• Welcome to the game of Twenty Questions!• Think of an animal and I will try to guess it• Does it have four legs?• yes• Does it have hooves?• no• Is it a dog?• yes• I won!• Keep playing?• yes• Think of another animal and I will try to guess

it• Does it have four legs?• no• Does it swim?• no• Is it an ostrich?• no• I give up! What is your animal• me!

Does it have 4 legs?

Does it swim?

Is it an Ostrich?

Is it aGoldfish?

Is it aDog?

Does it have hooves?

Is it aCow?

no

no no

yes

yes yes