AAA Week05
AAA Week05
Algorithms
Week # 5
Saima Gul
Sets and Dynamic Sets
Sets are fundamental to many operations and problems in
computer science.
The kind of sets we are used to from mathematics courses are
static sets.
However, the sets that we need in algorithmic problems are
usually dynamic sets.
In other words, most of the algorithms require to insert new
elements to and remove elements from the sets.
Hence, the sets we will be handling will change over time.
Furthermore, we will usually be using multisets.
2
Typical operations of dynamic sets
3
Data structures for representing
dynamic sets
Several data structures can be used for representing
dynamic sets (queues, linked lists, hash tables, rooted
trees, etc.)
Depending on the data structure, the implementation of
the basic operations of dynamic sets may have different
asymptotic running times.
It is important to be aware of various data types for
dynamic sets, to be able to make an informed decision to
pick a suitable data structure for a given application
area.
4
Binary Search Trees
5
What is a Binary Search Tree (BST)?
6
How to implement a BST?
implementation
of a node
parent implementation view
abstract view x1
left right
x1 6
6
key
x2 x5
x2 2 x5 8 2 8
x3 x4 x6
1 x3 x4 3 x6 9 1 3 9
red: keys of the nodes xi: name of the node key(xi): key value at node
7
Shorthand notations used for BST visualization
x1 6 x1 6
x2 2 x5 8
1 x3 x4 3 x6 9
8
BST Property
A BST is not just an arbitray binary tree.
We require the so called BST property:
Example:
x k
6
2 8
9
Repeated keys may exist
The keys at nodes need not be distinct.
1 6
1 3 9
10
Inorder walks over a BST
11
Inorder walks over a BST
Example:
InOrderWalk (x) { 6
if (x != NULL) {
InOrderWalk(left[ x ]);
print key[ x ]; 2 8
InOrderWalk(right[ x ]);
}
}
1 3 9
12
Searching in a BST
13
Searching in a BST
BST_Search (x,k) {
if (x == NULL)
return NULL; // to denote that k is not found
if (k==key[ x ])
return x; // i.e. return the pointer to the node with key k
if (k < key[ x ]) // k cannot be in the right subtree
return BST_Search(left[ x ], k);
else // k cannot be in the left subtree
return BST_Search(right[ x ], k);
}
Running time: The worst case appears when the number is not in
BST, and the search proceeds along the longest path from the root to
a leaf.
Hence, worst case running time is O(h), where h is the height (the size
of the longest path from the root to a leaf) of the tree.
14
Recursion vs. Iteration
Although it does not affect the asymptotic run time behavior, in
practice, iterative form of an algorithm runs faster than its recursive
implementation.
BST_Search_Iterative (x,k) {
while (x != NULL and k != key[ x ]) {
if (k < key[ x ]) // k cannot be in the right subtree
x = left[ x ]; // continue using the left subtree
else // k cannot be in the left subtree
x = right[ x ]; // continue using the right subtree
}
return x;
}
15
Minimum Operation
16
Minimum Operation
Actually, we cannot:
root
x
k Note that, x is not a leaf node…
17
Minimum Operation
Therefore, the minimum key stored in a BST can be
found by following the left child links (starting from the
root) as long as we can. The first node which does not
have a left child will have the minimum key in the BST.
BST_Minimum (x) {
while (left[ x ] != NULL) // if there exists a left child, its key is
x = left[ x ]; // smaller or equal to the current node
return x;
}
In the worst case, we can traverse the longest path in the BST.
running time: O(h)
18
Maximum Operation
19
Maximum Operation
Actually, we cannot:
root
x
k Note that, x is not a leaf node…
20
Maximum Operation
Therefore, the maximum key stored in a BST can be
found by following the right child links (starting from the
root) as long as we can. The first node which does not
have a right child will have the maximum key in the BST.
BST_Maximum (x) {
while (right[ x ] != NULL) // if there exists a right child, its key is
x = right[ x ]; // greater or equal to the current node
return x;
}
In the worst case, we can traverse the longest path in the BST.
running time: O(h)
21
Successor Operation
22
Successor Operation
23
Successor Operation
24
Successor Operation
Suppose x is the left child of its parent:
y
x
25
Successor Operation
Successor of x will be the closest ancestor y of x for
which x is in the left subtree of y (if exists).
BST_Successor (x) {
if (right[ x ] != NULL) // simple case
y return (BST_Minimum(x));
// find the closest ancestor of x
// for which x is in the left subtree
y = parent[ x ]; t = x;
while (y != NULL and t = right[ y ]) {
t = y;
x
y = parent[ t ];
}
return y;
} running time: O(h)
26
Insert Operation
27
Insert Operation
28
Insert Operation
A little harder:
into result
Insert 8 6 6
29
Insert Operation
General case:
into result
Insert 7 6 6
2 8 2 8
1 3 9 1 3 7 9
30
Insert Operation
General case:
into result
Insert 3 6 6
2 8 2 8
1 3 7 9 1 3 7 9
31
Pseudo code for Insert Operation
BST_Insert (T, x) { // T: the tree, x: a new node to be inserted
if (root[ T ] == NULL)
root[ T ] = x; // inserting into empty BST
else {
y = root[ T ]; // y follows a path to find the correct place for x
z = NULL; // z will simply follow y (value of y in previous iteration)
while (y != NULL) { // as long as we can go deeper in the BST
z = y; // make y follow z, and go into the correct subtree
y = (key[ x ] < key[ y ]) ? left[ y ] : right[ y ];
}
parent[ x ] = z; // z keeps the correct parent for x
if (key[ x ] < key[ z ]) // decide whether x will be a left or right child
left[ z ] = x;
else
right[ z ] = x;
}
}
running time: O(h)
32
Sorting using BSTs
33
Delete Operation
Delete operation will remove a given node from a BST.
Since this operation will also change the BST, we need
to make sure that after the removal of the given node,
the remaining tree satisfies the BST property.
Simplest case: Removing a leaf…
6
2 8
1 3 7 9
34
Pseudo code for leaf node deletion
BST_Delete_LeafNode (T, x) { // T: the tree, x: the leaf to be deleted
if (parent[ x ] == NULL) { // x is the only node in the tree
// the tree will become empty
root[ T ] = NULL;
}
else {
if (x == left[parent[ x ]]) // x is the left child of its parent
left[parent[ x ]] = NULL;
else // x is the right child of its parent
right[parent[ x ]] = NULL;
}
}
35
Delete Operation
A little bit harder: Removing a node with a single child…
y y y y
x x x x
z z z z
All the keys at z and below z are All the keys at z and below z are
smaller than equal to key[ y ] greater than equal to key[ y ]
Since the BST will satisfy the BST property before the removal, we
can simply make the only child of x the substitute child of parent of x.
36
Delete Operation
6 6
2 8 2
1 3 9 1 3 9
37
Delete Operation
1 3
1 3
38
Pseudo code for single child node deletion
BST_Delete_SingleChildNode (T, x) {
// T: the tree, x: the node to be deleted and it has a single child
child = (left[ x ] != NULL) ? left[ x ] : right[ x ]; // the only child of x
if (parent[ x ] == NULL) { // x is the root
// make that single child the new root
root[ T ] = child;
}
else { // x is not the root
if (x == left[parent[ x ]]) // x is the left child of its parent
left[parent[ x ]] = child;
else // x is the right child of its parent
right[parent[ x ]] = child;
}
}
40
Delete Operation
Most complex case: Removing a node with two children.
y
Removing the maximum node z takes constant time,
x since z is a node whose right child is missing (it has
at most one child – previous cases apply).
41
Delete Operation
Example for removing a node with two children.
node to be
deleted 10 10 10
6 18 5 18 5 18
2 7 29 2 7 29 2 7 29
5 5
4 z: max node 4 4
in the left
subtree
42
Pseudo code for complete Delete Operation
BST_Delete (T, x) { // T: the tree, x: the node to be deleted
if (left[ x ] == NULL and right[ x ] == NULL) // x is a leaf node
BST_Delete_LeafNode(T, x);
elseif (left[ x ] == NULL or right[ x ] == NULL) // a single child node
BST_Delete_SingleChildNode(T, x);
else { // x is a node with two children
// find max in the left subtree
z = BST_Maximum(left[ x ]); // needs O(h) time
key[ x ] = key[ z ]; // copy the max value
// no need to copy key[ x ] to max node as it
// will be immediately deleted
BST_Delete(T, z); // z : either leaf or has single child
}
} running time: O(h)
43
All dynamic operations run in O(h) time
2h-1 h
h elements
elements
Seems not…
44
All dynamic operations run in O(h) time
In the best case, BST will be a In the worst case, BST will be a
complete binary tree: Every nonleaf linked list: Every nonleaf node has
node has exactly two children and exactly one child:
all the leaves are at the same level:
h = O(lg n) h = O(n)
45
All dynamic operations run in O(h) time
46