CSE 326
Binary Search Trees
David Kaplan
Dept of Computer Science & Engineering
Autumn 2001
Binary Trees
Binary tree is A
a root
left subtree (maybe empty)
right subtree (maybe B C
empty)
D E F
Properties
max # of leaves:
G H
max # of nodes:
average depth for N nodes:
Data I J
Representation: left right
pointer pointer
Binary Search CSE 326 Autumn 2001
Trees 2
Binary Tree
Representation
A A
left right
child child
B C
B C
left right left right
child child child child D E F
D E F
left right left right left right
child child child child child child
Binary Search CSE 326 Autumn 2001
Trees 3
Dictionary ADT
Dictionary operations insert Adrien
Donald Roller-blade
create l33t haxtor
demon
destroy Hannah
insert C++ guru
Adrien find(Adrien)
find Roller-blade demon Dave
delete Older than dirt
…
Stores values associated with user-
specified keys
values may be any (homogeneous)
type
keys may be any (homogeneous)
comparable type
Binary Search CSE 326 Autumn 2001
Trees 4
Dictionary ADT:
Used Everywhere
Arrays
Sets
Dictionaries
Router tables
Page tables
Symbol tables
C++ structures
…
Anywhere we need to find things fast based on a
key
Binary Search CSE 326 Autumn 2001
Trees 5
Search ADT
Dictionary operations insert Adrien
Donald
create Hannah
destroy Dave
insert
find(Adrien) …
find Adrien
delete
Stores only the keys
keys may be any (homogenous) comparable
quickly tests for membership
Simplified dictionary, useful for examples (e.g.
CSE 326)
Binary Search CSE 326 Autumn 2001
Trees 6
Dictionary Data Structure:
Requirements
Fast insertion
runtime:
Fast searching
runtime:
Fast deletion
runtime:
Binary Search CSE 326 Autumn 2001
Trees 7
Naïve Implementations
unsorted sorted linked list
array array
insert O(n) find + O(1)
O(n)
find O(n) O(log n) O(n)
delete find + find + find +
O(1) O(1) O(1)
(mark-as- (mark-as-
deleted) deleted)
Binary Search CSE 326 Autumn 2001
Trees 8
Binary Search Tree
Dictionary Data Structure
Binary tree property
each node has 2 children 8
result:
storage is small
operations are simple 5 11
average depth is small
Search tree property
all keys in left subtree 2 6 10 12
smaller than root’s key
all keys in right subtree
larger than root’s key 4 7 9 14
result:
easy to find any given key
Insert/delete by changing links 13
Binary Search CSE 326 Autumn 2001
Trees 9
Example and Counter-
Example
8
5
5 11
4 8
2 7 6 10 18
1 7 11
4 15 20
3
NOT A 21
BINARY SEARCH TREE BINARY SEARCH TREE
Binary Search CSE 326 Autumn 2001
Trees 10
Complete Binary Search
Tree
Complete binary search
tree
(aka binary heap): 8
Links are completely
filled, except possibly
bottom level, which is 5 15
filled left-to-right.
3 7 9 17
1 4 6
Binary Search CSE 326 Autumn 2001
Trees 11
In-Order Traversal
10
visit left subtree
visit node
5 15
visit right subtree
2 9 20
What does this
guarantee with a
7 17 30 BST?
In order listing:
25791015172030
Binary Search CSE 326 Autumn 2001
Trees 12
Recursive Find
10
Node *
find(Comparable key, Node * t)
5 15
{
if (t == NULL) return t;
2 9 20
else if (key < t->key)
return find(key, t->left);
7 17 30
else if (key > t->key)
return find(key, t->right);
Runtime: else
Best-worse case? return t;
Worst-worse case? }
f(depth)?
Binary Search CSE 326 Autumn 2001
Trees 13
Iterative Find
10
Node *
find(Comparable key, Node * t)
5 15 {
while (t != NULL && t->key != key)
{
2 9 20
if (key < t->key)
t = t->left;
7 17 30 else
t = t->right;
}
return t;
}
Binary Search CSE 326 Autumn 2001
Trees 14
Insert
void
Concept: insert(Comparable x, Node * t)
Proceed down tree {
as in Find if ( t == NULL ) {
If new key not t = new Node(x);
found, then insert } else if (x < t->key) {
a new node at last insert( x, t->left );
spot traversed
} else if (x > t->key) {
insert( x, t->right );
} else {
// duplicate
// handling is app-dependent
}
Binary Search CSE 326 Autumn 2001
Trees 15
BuildTree for BSTs
Suppose the data 1, 2, 3, 4, 5, 6, 7, 8, 9 is
inserted into an initially empty BST:
in order
in reverse order
median first, then left median, right median,
etc.
Binary Search CSE 326 Autumn 2001
Trees 16
Analysis of BuildTree
Worst case is O(n2)
1 + 2 + 3 + … + n = O(n2)
Average case assuming all orderings equally likely:
O(n log n)
averaging over all insert sequences (not over all binary
trees)
equivalently: average depth of a node is log n
proof: see Introduction to Algorithms, Cormen, Leiserson, &
Rivest
Binary Search CSE 326 Autumn 2001
Trees 17
BST Bonus:
FindMin, FindMax
Find minimum
10
5 15
Find maximum
2 9 20
7 17 30
Binary Search CSE 326 Autumn 2001
Trees 18
Successor Node
Next larger node
10
in this node’s subtree
Node * succ(Node * t) { 5 15
if (t->right == NULL)
return NULL;
else
2 9 20
return min(t->right);
}
7 17 30
How many children can the successor of a node have?
Binary Search CSE 326 Autumn 2001
Trees 19
Predecessor Node
Next smaller node
10
in this node’s subtree
Node * pred(Node * t) { 5 15
if (t->left == NULL)
return NULL;
else 2 9 20
return max(t->left);
}
7 17 30
Binary Search CSE 326 Autumn 2001
Trees 20
Deletion
10
5 15
2 9 20
7 17 30
Why might deletion be harder than insertion?
Binary Search CSE 326 Autumn 2001
Trees 21
Lazy Deletion
Instead of physically deleting
nodes, just mark them as
deleted
+ simpler 10
+ physical deletions done in
batches
5 15
+ some adds just flip deleted flag
- extra memory for deleted flag
- many lazy deletions slow finds 2 9 20
- some operations may have to
be modified (e.g., min and max) 17 30
7
Binary Search CSE 326 Autumn 2001
Trees 22
Lazy Deletion
Delete(17)
10
Delete(15)
Delete(5) 5 15
Find(9) 2 9 20
Find(16)
7 17 30
Insert(5)
Find(17)
Binary Search CSE 326 Autumn 2001
Trees 23
Deletion - Leaf Case
Delete(17) 10
5 15
2 9 20
7 17 30
Binary Search CSE 326 Autumn 2001
Trees 24
Deletion - One Child Case
Delete(15) 10
5 15
2 9 20
7 30
Binary Search CSE 326 Autumn 2001
Trees 25
Deletion - Two Child Case
Replace node with
descendant whose value is 10
guaranteed to be between
left and right subtrees: the 5 20
successor
2 9 30
Delete(5)
7
Could we have used predecessor instead?
Binary Search CSE 326 Autumn 2001
Trees 26
Delete Code
void delete(Comparable key, Node *& root) {
Node *& handle(find(key, root));
Node * toDelete = handle;
if (handle != NULL) {
if (handle->left == NULL) { // Leaf or one child
handle = handle->right;
delete toDelete;
} else if (handle->right == NULL) { // One child
handle = handle->left;
delete toDelete;
} else { // Two children
successor = succ(root);
handle->data = successor->data;
delete(successor->data, handle->right);
}
}
}
Binary Search CSE 326 Autumn 2001
Trees 27
Thinking about
Binary Search Trees
Observations
Each operation views two new elements at a time
Elements (even siblings) may be scattered in
memory
Binary search trees are fast if they’re shallow
Realities
For large data sets, disk accesses dominate runtime
Some deep and some shallow BSTs exist for any data
Binary Search CSE 326 Autumn 2001
Trees 28
Beauty is Only (log n)
Deep
Binary Search Trees are fast if they’re shallow:
perfectly complete
complete – possibly missing some “fringe” (leaves)
any other good cases?
What matters?
Problems occur when one branch is much longer than
another
i.e. when tree is out of balance
Binary Search CSE 326 Autumn 2001
Trees 29
Dictionary
Implementations
unsorted sorted linked BST
array array list
inser O(n) find + O(1) O(Dept
t O(n) h)
find O(n) O(log n) O(n) O(Dept
h)
delet find + find + find + O(Dept
e O(1) O(1) O(1) h)
(mark-as- (mark-as-
deleted) deleted)
BST’s looking good for shallow trees, i.e. if Depth is
small (log n); otherwise as bad as a linked list!
Binary Search CSE 326 Autumn 2001
Trees 30
Digression: Tail Recursion
Tail recursion: when the tail (final
operation) of a function recursively calls
the function
Why is tail recursion especially bad with
a linked list?
Why might it be a lot better with a tree?
Why might it not?
Binary Search CSE 326 Autumn 2001
Trees 31
Making Trees Efficient:
Possible Solutions
Keep BSTs shallow by maintaining
“balance”
AVL trees
… also exploit most-recently-used (mru) info
Splay trees
Reduce disk access by increasing branching
factor
B-trees
Binary Search CSE 326 Autumn 2001
Trees 32