Title: Binary Search Trees (BSTs)
1Binary Search Trees (BSTs)
- What is a Binary search tree?
- Why Binary search trees?
- Binary search tree implementation
- Insertion in a BST
- Deletion from a BST
- TreeSort
- BSTs as Priority Queues
2Binary Search Tree (Definition)
- A binary search tree (BST) is a binary tree that
is empty or that satisfies the BST ordering
property - The key of each node is greater than each key in
the left subtree, if any, of the node. - The key of each node is less than each key in the
right subtree, if any, of the node. - Thus, each key in a BST is unique.
- Examples
- Note The literature contains three other
definitions for BST that allow duplicate keys in
a BST. For any node x - keyleftSubtree(x) ? keyx lt
keyrightSubtree(x) - keyleftSubtree(x) lt keyx ?
keyrightSubtree(x) - keyleftSubtree(x) ? keyx ?
keyrightSubtree(x) - We will not use any of these definitions in this
course.
3Binary Search Tree (Definition) (Contd.)
- A common misunderstanding is that the BST
ordering property is only between parents and
children, rather than all the values in left and
right subtrees. It is a common error to interpret
the BST ordering property as - The key of each node is greater than the key of
the left child of that node, if any. - The key of each node is less than the key of the
right child of that node, if any - Example
The above is not a BST because both 22 and 25
cannot be on the left subtree of 20 however each
node satisfies the BST property with respect to
its two children.
4Why BSTs?
- 1. BSTs provide good logarithmic time performance
in the best and average cases. - Average case complexities of using linear data
structures compared to BSTs
Traversal Deletion Insertion Retrieval or Search Data Structure
O(n) O(log n) O(log n) O(log n) BST
O(n) O(n) O(n) O(log n) (using Binary Search) Sorted Array
O(n) O(n) O(1) O(n) Unsorted Array
O(n) O(n) O(n) O(n) Sorted Linked List
O(n) O(n) O(1) O(n) LinkedList
Note BST worst execution time for each of the
above operations is O(n) when the tree is linear
5Why BSTs? (Contd.)
- 2. Binary Search Trees (BSTs) are an important
data structure for dynamic sets and - Dictionaries
- Each element is an Association
object having a Comparable key and an - Object value
- Dynamic sets support queries such as
- Search(x), Minimum(), Maximum(), Successor(x),
Predecessor(x) - They also support modifying operations like
Insert(x) and Delete(x) - 3. BSTs can be used to implement priority queues
- 4. BSTs are used in TreeSort
6Binary Search Tree Implementation
- The BinarySearchTree class inherits the instance
variables key, left, and right of the BinaryTree
class
public class BinarySearchTree extends BinaryTree
implements
SearchableContainer private BinarySearchTree
getLeftBST() return (BinarySearchTree)
getLeft( ) private BinarySearchTree
getRightBST( ) return (BinarySearchTree)
getRight( ) // . . .
7Binary Search Tree Implementation find
- The recursive find method of the BinarySearchTree
class
public Comparable find(Comparable target)
if(isEmpty()) return null
Comparable currentKey (Comparable) key
int comparison target.compareTo(current
Key) if(comparison 0)
return currentKey else if(comparison lt
0) return getLeftBST().find(target)
else return
getRightBST().find(target)
8Binary Search Tree Implementation findIterative
- The iterative find method of the BinarySearchTree
class
public Comparable findIterative(Comparable
target) if(isEmpty()) return
null BinarySearchTree tree this
while(!tree.isEmpty()) Comparable
currentKey (Comparable) key int
comparison currentKey.compareTo(target)
if(comparison 0) return
currentKey else if(comparison lt 0)
tree tree.getLeftBST()
else tree tree.getRightBST()
return null
9Binary Search Tree Implementation findMin
- The findMin method of the BinarySearchTree class
- By the BST ordering property, the minimum key is
the key of the left-most node that has an empty
left-subtree.
public Comparable findMin()
if(isEmpty()) return null
if(getLeftBST().isEmpty()) return
(Comparable)getKey() else
return getLeftBST().findMin()
Exercise Write the iterative findMin
10Binary Search Tree Implementation findMax
- The findMax method of the BinarySearchTree class
- By the BST ordering property, the maximum key is
the key of the right-most node that has an empty
right-subtree.
public Comparable findMax() if(isEmpty())
return null if(getRightBST().isEmpty())
return (Comparable)getKey() else return
getRightBST().findMax()
Exercise Write the iterative findMax
11Binary Search Tree Implementation findSuccessor
- The successor of a key x is the smallest key
greater than x. - If(x has a non-empty right subtree)
- Successor of x is the minimum value in the right
subtree of x - else
- if(x is maximum value in tree)
- x has no successor
- else
- successor is smallest ancestor of x that
is greater than x -
successor key
7 4
10 9
20 15
32 30
40 35
No successor 40
Example
12Binary Search Tree Implementation findSuccessor
(Contd.)
public Comparable findSuccessor(Comparable x)
if(isEmpty()) throw new IllegalArgumentExceptio
n("Tree is empty") else return
findSuccessor(x, (Comparable)getKey())
private Comparable findSuccessor(Comparable x,
Comparable successor) if(isEmpty()) throw
new IllegalArgumentException(x " is not in
tree") Comparable currentKey
(Comparable)getKey() int comparison
x.compareTo(currentKey) if(comparison
0) if(!getRightBST().isEmpty())
return getRightBST().findMin() else
if(getRightBST().isEmpty() successor.compareTo(
x) lt 0) // x is max value in tree
throw new IllegalArgumentException(x " has no
successor") else return successor
else if(comparison lt 0)
return getLeftBST().findSuccessor(x,
currentKey) else return
getRightBST().findSuccessor(x, successor)
13Binary Search Tree Implementation findPredecessor
- The predecessor of a key x is the largest key
smaller than x. - If(x has a non-empty left subtree)
- predecessor of x is the maximum value in the
left subtree of x - else
- if(x is minimum value in tree)
- x has no predecessor
- else
- predecessor is the last ancestor of x
that is smaller than x (on the path from - root to the node x)
-
predecessor key
No predecessor 4
7 9
10 15
30 32
32 35
35 40
Example
14Binary Search Tree Implementation findPredecesor
(Contd.)
public Comparable findPredecessor(Comparable x)
if(isEmpty()) throw new IllegalArgumentExcepti
on("Tree is empty") else if(x.equals(getKey(
)) getLeftBST().isEmpty()) throw new
IllegalArgumentException(x " has no
predecessor") else return
findPredecessor(x, (Comparable)getKey())
private Comparable findPredecessor(Comparable
x, Comparable predecessor) if(isEmpty())
throw new IllegalArgumentException(x " is not
in tree") Comparable currentKey
(Comparable)getKey() int comparison
x.compareTo(currentKey) if(comparison
0) if(!getLeftBST().isEmpty()) return
getLeftBST().findMax() else
if(getLeftBST().isEmpty() predecessor.compareTo
(x) gt 0) // x is min value in tree throw
new IllegalArgumentException(x " has no
predecessor") else return
predecessor else if(comparison gt 0)
return getRightBST().findPredecessor(x,
currentKey) else return
getLeftBST().findPredecessor(x, predecessor)
15Insertion in a BST
- By the BST ordering property, a new node is
always inserted as a leaf node. - The insert method, given in the next page,
recursively finds an appropriate empty subtree to
insert the new key. It then transforms this empty
subtree into a leaf node by invoking the
attachKey method
public void attachKey(Object obj)
if(!isEmpty()) throw new
InvalidOperationException() else
key obj left new
BinarySearchTree() right new
BinarySearchTree()
16Insertion in a BST (Contd.)
public void insert(Comparable comparable)
if(isEmpty()) attachKey(comparable) else
Comparable key (Comparable) getKey()
if(comparable.compareTo(key)0)
throw new IllegalArgumentException("duplicate
key") else if (comparable.compareTo(key)lt0)
getLeftBST().insert(comparable) else
getRightBST().insert(comparable)
5
5
1
1
1
1
5
17Deletion in a BST
- There are three cases
- The node to be deleted is a leaf node.
- The node to be deleted has one non-empty child.
- The node to be deleted has two non-empty children.
18CASE 1 Deleting a Leaf Node
Convert the leaf node into an empty tree by using
the detachKey method
// In Binary Tree class public Object
detachKey( ) if(! isLeaf( )) throw new
InvalidOperationException( ) else
Object obj key key null
left null right null
return obj
Delete 5
19CASE 2 Deleting a one-child node
- CASE 2 THE NODE TO BE DELETED HAS ONE NON-EMPTY
CHILD - (a) The right subtree of the node x to be deleted
is empty. - Example
// Let target be a reference to the node
x. BinarySearchTree temp target.getLeftBST() ta
rget.key temp.key target.left
temp.left target.right temp.right temp null
target
target
20
Delete 10
temp
5
35
8
3
22
40
6
25
20CASE 2 Deleting a one-child node (Contd)
- (b) The left subtree of the node x to be deleted
is empty. -
- Example
// Let target be a reference to the node
x. BinarySearchTree temp target.getRightBST() t
arget.key temp.key target.left
temp.left target.right temp.right temp null
Delete 8
21CASE 3 DELETING A NODE THAT HAS TWO NON-EMPTY
CHILDREN
- DELETION BY COPYING METHOD1
- Copy the minimum key in the right subtree of x
to the node x, then delete the one-child or
leaf-node with this minimum key. - Example
22CASE 3 DELETING A NODE THAT HAS TWO NON-EMPTY
CHILDREN (Contd.)
- DELETION BY COPYING METHOD2
- Copy the maximum key in the left subtree
of x to the node x, then delete the one-child or
leaf-node with this maximum key. - Example
23Deletion by Copying Method1 implementation
// find the minimum key in the right subtree of
the target node Comparable min
target.getRightBST().findMin() // copy the
minimum value to the target target.key min
// delete the one-child or leaf node having the
min target.getRightBST().withdraw(min)
Note All the different cases for deleting a node
are handled in the withdraw (Comparable key)
method of BinarySearchTree class
24Tree Sort
- Any of the following in-order traversal behaviour
of BST can be used to implement a sorting
algorithm on an array of distinct elements - The in-order traversal of a BST visits the
nodes of the tree in increasing - sorted order
- The reverse in-order traversal of a BST visits
the nodes in decreasing - sorted order
- This algorithm is called TreeSort.
Example
In-order Traversal 4, 7, 9, 10, 15, 20, 25, 30,
32, 35, 40
Reverse in-order Traversal 40, 35, 32, 30, 25,
20, 15, 10, 9, 7, 4
25Tree Sort (Contd.)
- TreeSort algorithm
- Insert the array elements in a BST
- Perform an in-order traversal on the BST,
storing each visited value in the - corresponding array location
public static void treeSort(int x)
BinarySearchTree tree buildBST(x) if(tree
null) throw new IllegalArgumentExcepti
on("Error Duplicate keys") else
int index 0 // need to pass index by
reference tree.treeSort(x, index)
private void treeSort(int x, int
index) if(isEmpty()) return else
getLeftBST().treeSort(x, index) int
k index0 xk (Integer)
getKey() index0 k 1
getRightBST().treeSort(x, index)
26Tree Sort (Contd.)
private static BinarySearchTree buildBST(int
x) // x must have distinct values
BinarySearchTree tree new BinarySearchTree(
) for(int k 0 k lt x.length k)
try tree.insert(new
Integer(xk))
catch(IllegalArgumentException e)
tree null
return tree
27Tree Sort (Contd.)
- An alternative TreeSort algorithm is
- Insert the array elements in a BST
- for(int k 0 k lt array.length k)
- arrayk bst.Min()
- bst.exractMin()
-
public static void treeSort(int x)
BinarySearchTree tree buildBST(x) if(tree
null) throw new IllegalArgumentExcept
ion("Error Duplicate keys") else
for(int k 0 k lt x.length k)
Comparable min tree.findMin() xk
(Integer) min tree.withdraw(min)
28Tree Sort (Contd.)
Adding items to a binary search tree is on
average an O(log n) process, so adding n items is
an O(n log n) process. But adding an item to an
unbalanced binary tree needs O(n) time in the
worst-case, when the tree resembles a linked list
(degenerate tree), causing a worst case of O(n2)
for this sorting algorithm. The worst case
scenario happens when Tree Sort algorithm sorts
an already sorted array. This would make the time
needed to insert all elements into the binary
tree O(n2). The worst-case behaviour can be
improved upon by using a Self-balancing binary
search tree such as AVL tree. Using such a tree,
the algorithm has an O(n log n) worst-case
performance.
29BSTs as Priority Queues
By using insert and withdrawMax or WithdrawMin a
BST can be used as a priority queue in which the
keys of the elements are distinct.