Transcript Lecture 9

Binary Trees
CS 110: Data Structures and Algorithms
First Semester, 2010-2011
Binary Tree
► An
ordered tree with just two children
► Distinguished between “left” and “right” child
► Has a lot of uses, like heaps, expression trees,
etc.
Binary Tree Properties
► Let
► Properties
►
n – number of nodes
►
e=i+1
►
e – external nodes
►
n = 2e – 1
►
i – internal nodes
►
h≤i
►
h – height
►
h ≤ (n-1) / 2
►
e ≤ 2n
►
h ≥ log2 e
►
h ≥ log2 (n+1) - 1
Binary Tree Implementation
► Array
►
►
Elements are stored in an array
►
Relationships are derived using indices
Linked List Implementation
►
►
►
Implementation
Elements stored in a TreeNode, similar to the Node
class used in Stack and Queue
Each TreeNode has pointers to the element it contains,
and then TreeNode references to its children
Ideas here can be extended to implement other
types of trees
Binary Tree Implementation
► Each
element is stored in an array
► Root of the array is at array[0]
► Left child of the node at index j is at
array[2j+1]
► Right
child of the node at index j is at array[2j+2]
► How do you compute for the parent of the node
at index j?
Binary Tree Array Example
A
B
C
D
E
F
H
A
B
C
D
E
F
G
0
1
2
3
4
5
6
H
7
8
9
10 11 12 13 14 15
G
Linked List Implementation
► Each
element is stored in a TreeNode object
► TreeNode has “left” and “right” TreeNode
fields, which correspond to its children
► TreeNode also has a “parent” field
BT Linked List Implementation
Ø
left
right
A
Ø
B
Ø
Ø
D
C
Ø
Ø
E
Ø
Ø
G
Tree Search Algorithms
► Given
a root of a tree, find a particular element
► Two approaches
►
Breadth First Search
►
Depth First Search
Breadth First Search
► Search
per level
Root first
► Children of root
► Children of the children of the root
► Etc
►
► Search
left’s children before right’s
► Can be applied to other trees
Breadth First Search
A
B
D
C
E
H
► Top
to bottom, left to right
► A, B, C, D, E, F, G, H
F
G
Breadth First Search
► Implementation
requires a Queue data
structure
► Put the root in the queue
► Dequeue an element from the queue
If it’s the element we’re looking for, return
► Otherwise, queue its left and right child
►
► Repeat
until the queue is empty, or until the
element is found
Breadth First Search
public TreeNode BFS(TreeNode root, Object element) {
Queue q = new NodeQueue();
q.enqueue(root);
while( !q.isEmpty() ) {
TreeNode n = (TreeNode) q.dequeue();
if ( n.getElement().equals(element) ) {
return n;
}
if ( q.getLeft() != null ) q.enqueue( q.getLeft() );
if ( q.getRight() != null ) q.enqueue( q.getRight() );
}
}
Depth First Search
► Start
from the root, search downward
► Explore as far as possible until the goal node is
reached, or there are no more children
► Backtrack when there are no more children
► Search the left branch before the right branch
Depth First Search
A
B
D
C
E
F
H
► Drill
down, then go back, then right
► A, B, D, E, H, C, F, G
G
Depth First Search
► Adapt
the code from the BFS, except use a
Stack instead of a Queue
►
Push the right child FIRST
► Better
solution is to use recursion
Check the current node’s element
► If it is not what is being searched
►
► DFS
subtree rooted at the left child
► DFS
subtree rooted at the right child
Depth First Search
public TreeNode DFS(TreeNode root, Object element) {
if ( root.getElement().equals(element) ) {
return root;
}
TreeNode ret = null;
if ( root.getLeft() != null ) {
ret = DFS( root.getLeft(), element );
}
if ( ret != null ) return ret;
if ( root.getRight() != null ) {
ret = DFS( root.getRight(), element );
}
return ret;
}