COS 212
BST: Depth-First
Traversals, Insertion &
Deletion
Binary Search Tree (BST)
An ordered binary tree (a.k.a. binary search tree)
is a binary tree where for each node n:
Values stored in the left subtree of a node n are less than the
value stored in n
Values stored in the right subtree of a node n are greater
than the value stored in n
Traversing a tree: breadth-first VS depth-
first
8
5 6 A
y
3 7 1 D
z
1 6 9 C E
Depth-first Traversal
Depth-first:
Traverse as deep as possible for each child before going
to the next child.
Go through the tree branch-by-branch.
3 7
1 6 9
Question: when traversing a tree, what do we output
first: the parent or the children?
Three DF traversal types: preorder, inorder, postorder
Depth-first Traversal
Preorder traversal: Parent first
Parent is visited first, then its children are visited
public void preorder() {
preorder(root);
5 }
protected void
preorder(BSTNode<T> p)
3 7 {
if (p != null) {
visit(p);
preorder([Link]);
1 6 9
preorder([Link]);
}
}
5 3 1 7 6 9
Depth-first Traversal
Inorder traversal: Left, Parent, Right
Left child is visited first, then parent, then the right child
public void inorder() {
5 inorder(root);
}
protected void
inorder(BSTNode<T> p)
3 7 {
if (p != null) {
inorder([Link]);
visit(p);
1 6 9
inorder([Link]);
}
}
1 3 5 6 7 9
Depth-first Traversal
Postorder traversal: Children first
Children are visited first, then the parent
public void postorder()
{
5 postorder(root);
}
protected void
postorder(BSTNode<T> p)
3 7 {
if (p != null) {
postorder([Link]);
1 6 9
postorder([Link]);
visit(p);
}
}
1 3 6 9 7 5
Depth-first Traversal
protected void preorder(BSTNode<T> Traversal
p) algorithms are
{ elegant. But
if (p != null) { are they
visit(p);
preorder([Link]); efficient?
preorder([Link]);
}
} protected void inorder(BSTNode<T>
p)
{
if (p != null) {
inorder([Link]);
visit(p);
inorder([Link]);
}
}
protected void
postorder(BSTNode<T> p)
{
if (p != null) {
postorder([Link]); Space & time
postorder([Link]); efficiency: O(n)
visit(p);
}
}
Inserting a node into BST
We know how to search & traverse the BST
How do we add new nodes?
To maintain BST structure, apply the search
algorithm to the BST, and insert the node at the
empty leaf location where the algorithm takes you
Insert 4 into the following tree:
5 5
3 7 3 7
1 6 9 1 4 6 9
Inserting a node into BST Can we rewrite this
algorithm
recursively?
insert(el)
if root is null // tree is empty; Yes – see
root becomes a new node with el; prescribed
textbook
return;
p = root;
while p is not null // find a place for inserting new
node;
prev = p;
if el < element in node p How many paths
through the tree do
p = [Link]; we take?
else p = [Link];
if el < element in node prev
new node with el is attached to the left of prev;
else new node with el is attached to the right of prev;
Inserting a node into BST
20 30
null 20
25 10 15
20 20 20
30 30 10 30
25 25
Deleting a node from BST
How do we delete nodes?
First, use the search algorithm to find it
Deleting a leaf is easy:
5 5
3 7 3 7
1 4 6 9 1 6 9
Deleting a node from BST
Deleting a node with a single child is easy, too:
5 5
3 7 1 7
1 6 9 6 9
Deleting a node from BST
Deleting a node with two children is less obvious:
3 3
1 8 1
6 10 6 10
5 7 5 7
Delete by merging
Property of BST:
3
all nodes to the left of n will be < n
all nodes to the right of n will be > n
1 8 n
If we take the largest node on
the left of n, it will be:
6 10
> than all other nodes on the left
< than all the nodes to the right of n
It will always be the rightmost node of
the left branch 5 7
The rightmost node in the left branch
of n can become a parent to the right Rightmost
branch of n node to the
left of n
Delete by merging
1. Start from the root
2. Find the node to be deleted
3. Go left, then find the rightmost node in the left subtree
4. The right subtree of n becomes the right subtree of the
rightmost node
5. The left child of n takes n’s place
3 3
1 8 1 6
6 10 5 7
5 7 10
Delete by merging: Tree Height
Deletion by merging
can have an adverse
effect on the tree
height
Delete by Copying
Deletion by merging may change 3
the height of the tree and make it
inefficient
Is there a better way? 1 8 n
If we take the rightmost node on
the left, it will be: 6 10
> than all nodes in the left branch
< than all the nodes in the right branch
Thus, it is a perfect candidate to replace
5 7
the deleted node!
Instead of moving around
subtrees, we could just take the
rightmost node of the left Rightmost
node to the
subtree, and replace n with it left of n
Delete by Copying
3 3
1 8 1 7
6 10 6 10
5 7 5
But what if the rightmost node has children?
It’s rightmost, so there is no right child
If there is a left child, it simply becomes the right child of
the rightmost node’s parent.
Delete by Copying
20 20 15
10 30 10 27 10 27
15 25 35 15
1 25 35 25 35
5
2327
27 2326 2326
26
delete delete
30 20
Other functions: FindMin and
FindMax
What is the easiest way to find the
3
smallest value in a BST?
Start at the root, go as far left as you
can.
1 8
Leftmost node MUST be the smallest!
…Largest value in a BST? 6 10
Same, but you need to go right instead
of left
Rightmost node is the largest 5 7
findMax (Node n) {
if (n != null) {
while([Link] !=
null) How many paths
n = [Link]; through the tree do
}
we take?
return n;
}
1
Other functions: countLeft 3
What if you need to traverse the 1 8 1
0
entire BST?
Example: count how many left children
are in the tree.
1 6 10 0
Both left and right branch can have their
own left children!
Solution: modify depth-first
0 5 7 0
traversal
protected void preorder(BSTNode<T>
p)
{ protected int countLeft(BSTNode<T> p)
if (p != null) { {
visit(p); if (p == null) return 0;
preorder([Link]); else {
preorder([Link]); if([Link] != null)
} return 1 + countLeft([Link])
} +
countLeft([Link]);
else return
countLeft([Link]);
}
}
Summary
Depth-first traversal
3
Preorder, inorder, postorder
Insertion into BST 1 8
Search for an empty leaf position
Deletion from BST 6 10
By merging
By copying
5 7
Other functions
One path followed: implement iteratively
Entire tree needs to be traversed:
implement recursively