You are on page 1of 125

Binary Search Trees

Trees
• Linear access time of linked lists is prohibitive
– Does there exist any simple data structure for
which the running time of most operations
(search, insert, delete) is O(log N)?
Trees
• A tree is a collection of nodes
– The collection can be empty
– (recursive definition) If not empty, a tree consists
of a distinguished node r (the root), and zero or
more nonempty subtrees T1, T2, ...., Tk, each of
whose roots are connected by a directed edge
from r
Some Terminologies

• Child and parent


– Every node except the root has one parent 
– A node can have an arbitrary number of children
• Leaves
– Nodes with no children
• Sibling
– nodes with same parent
Some Terminologies
• Path
• Length
– number of edges on the path
• Depth of a node
– length of the unique path from the root to that node
– The depth of a tree is equal to the depth of the deepest leaf
• Height of a node
– length of the longest path from that node to a leaf
– all leaves are at height 0
– The height of a tree is equal to the height of the root
• Ancestor and descendant
– Proper ancestor and proper descendant
Example: UNIX Directory
Binary Trees
• A tree in which no node can have more than two children

• The depth of an “average” binary tree is considerably smaller than N,


eventhough in the worst case, the depth can be as large as N – 1.
Example: Expression Trees

• Leaves are operands (constants or variables)


• The other nodes (internal nodes) contain operators
• Will not be a binary tree if some operators are not binary
A Taxonomy of Trees
• General Trees – any number of children /
node

• Binary Trees – max 2 children / node

– Heaps – parent < (>) children

– Binary Search Trees


Binary Trees

• Binary search tree


– Every element has a unique key.
– The keys in a nonempty left subtree (right
subtree) are smaller (larger) than the key in the
root of subtree.
– The left and right subtrees are also binary
search trees.
Binary Search Trees

• Binary Search Trees (BST) are a type of Binary


Trees with a special organization of data.
• This data organization leads to O(log n)
complexity for searches, insertions and deletions
in certain types of the BST (balanced trees).
– O(h) in general
Binary Search Algorithm
Binary Search algorithm of an array of sorted items reduces the search space
by one half after each comparison

34 41 56 63 72 89 95
0 1 2 3 4 5 6

34 41 56 72 89 95
0 1 2 4 5 6

72 95
34 56
4 6
0 2
Organization Rule for BST
• the values in all nodes in the left subtree of a node are less than
the node value
• the values in all nodes in the right subtree of a node are greater
than the node values

63

41 89

72 95
34 56
Binary Tree
struct bstnode {
int data;
struct bstnode *left, *right;
};
BST Operations: Search
Searching in the BST
method search(key)
• implements the binary search based on comparison of the
items
in the tree

• the items in the BST must be comparable (e.g integers, string,


etc.)

The search starts at the root. It probes down, comparing the


values in each node with the target, till it finds the first item equal
to the target. Returns this item or null if there is none.
Search in BST - Pseudocode

if the tree is empty


return NULL

else if the item in the node equals the target


return the node value

else if the item in the node is greater than the target


return the result of searching the left subtree

else if the item in the node is smaller than the target


return the result of searching the right subtree
Search in a BST: C code

struct bstnode* search(struct bstnode* root,


int data)
{
if ((root==NULL)||(root->data == data)
return root;
if (data<root->data)
return search(root->left,data);
return search(root->right,data);
}
BST Operations: Insertion
method insert(key)
 places a new item near the frontier of the BST while retaining
its organization of data:
starting at the root it probes down the tree till it finds a
node whose left or right pointer is empty and is a logical place
for the new value
uses a binary search to locate the insertion point
is based on comparisons of the new item and values of
nodes in the BST
Elements in nodes must be comparable!
Case 1: The Tree is Empty
Set the root to a new node containing the item
Case 2: The Tree is Not Empty
Call a recursive helper method to insert the
item 10 > 7
10

7
10 > 9
5 9

4 6 8 10
Insertion in BST - Pseudocode

if tree is empty
create a root node with the new key
else if key > node key
compare key with the right subtree:
if subtree is empty create a leaf node
else add key in right subtree
else key < node key
compare key with the left subtree:
if the subtree is empty create a leaf node
else add key to the left subtree
Creating newnode into a BST: C code

struct bstnode *newNode(int item)


{
struct bstnode *temp=(struct bstnode
*)malloc(sizeof(struct bstnode));
    temp->key = item;
    temp->left = temp->right = NULL;
    return temp;
}
Insertion into a BST: C code

struct bstnode* insert(struct bstnode* node, int key)


{
    /* If the tree is empty, return a new node */
    if (node == NULL) return newNode(key);
 
    /* Otherwise, recur down the tree */
    if (key < node->key)
        node->left  = insert(node->left, key);
    else if (key > node->key)
        node->right = insert(node->right, key);  
 
    /* return the (unchanged) node pointer */
    return node;
}
Traversal in BST
• Inorder
• Preorder
• Postorder
In-Order Traversal Procedure
procedure In_Order(cur iot in Ptr toa
Tree_Node)

if( cur <> NIL ) then


In_Order( cur^.left_child )
Do_Something( cur^.data )
In_Order( cur^.right_child )
endif
C code:
endprocedure // In_Order void inorder(struct bstnode *root)
{
    if (root != NULL)
    {
        inorder(root->left);
        printf("%d \n", root->key);
        inorder(root->right);
    }
}
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
P print(data) 22
R InOrderPrint(right
child)

9 67

3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
P print(data) 22
R InOrderPrint(right
child)

9 67

3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
P print(data) 22
R InOrderPrint(right
child)

9 67

3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)

9 67

3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)

9 67

3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67

3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67

3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67

L 3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67

L 3 14 36 94

1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67

L 3 14 36 94

L 1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67

L 3 14 36 94

L 1 7 44 97
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1

L 3 14 36 94

L 1 7 44 97
P
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1

L 3 14 36 94

L 1 7 44 97
P
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1

L 3 14 36 94

L 1 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1

L 3 14 36 94

L 1 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1

L 3 14 36 94

L 1 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3

L 3 14 36 94
P

L 1 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3

L 3 14 36 94
P

L 1 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3

L 3 14 36 94
P
R

L 1 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3

L 3 14 36 94
P
R

L 1 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3

L 3 14 36 94
P
R

L 1 L 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3

L 3 14 36 94
P
R

L 1 L 7 44 97
P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9
P

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9
P

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9
P
R

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9
P
R

L 3 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9
P
R

L 3 L 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9
P
R

L 3 L 14 36 94
P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9 14
P
R

L 3 L 14 36 94
P P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9 14
P
R

L 3 L 14 36 94
P P
R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9 14
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9 14
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9 14
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data)
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9 14
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9 14 22
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Continue?

Enough
Yes!
Already!
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right
child)
L 9 67
Output: 1 3 7 9 14 22
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 67
Output: 1 3 7 9 14 22
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 67
Output: 1 3 7 9 14 22
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
R

L 3 L 14 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
R

L 3 L 14 L 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
R

L 3 L 14 L 36 94
P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36
R

L 3 L 14 L 36 94
P P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36
R

L 3 L 14 L 36 94
P P P
R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36
R

L 3 L 14 L 36 94
P P P
R R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36
R

L 3 L 14 L 36 94
P P P
R R R

L 1 L 7 44 97
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36 44
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36 44
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36 44
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36 44
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36 44
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P
36 44
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67
R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67
R R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67
R R

L 3 L 14 L 36 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67
R R

L 3 L 14 L 36 L 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67
R R

L 3 L 14 L 36 L 94
P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94
R R

L 3 L 14 L 36 L 94
P P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94
R R

L 3 L 14 L 36 L 94
P P P P
R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94 97
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94 97
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P P
R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94 97
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P P
R R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94 97
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P P
R R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94 97
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P P
R R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94 97
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P P
R R R R
Proc InOrderPrint(pointer)
root
pointer NOT NIL?
L InOrderPrint(left child)
L 22
P print(data) P
R InOrderPrint(right R
child)
L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94 97
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P P
R R R R
Algorithm Example
root
. . .
InOrderPrint(root
) L 22
P
. . . R

L 9 L 67
Output: 1 3 7 9 14 22
P P
36 44 67 94 97
R R

L 3 L 14 L 36 L 94
P P P P
R R R R

L L L 44 L 97
1 7
P P P P
R R R R
Preorder Traversal
• Algorithm Preorder(tree)
1. Visit the root.
2. Traverse the left subtree, i.e., call
Preorder(left-subtree)
3. Traverse the right subtree, i.e., call
Preorder(right-subtree)
Preorder
void printPreorder(struct bstnode* node)
{
     if (node == NULL)
          return;
 
     /* first print data of node */
     printf("%d ", node->data); 
 
     /* then recur on left sutree */
     printPreorder(node->left); 
 
     /* now recur on right subtree */
     printPreorder(node->right);
}   
Postorder Traversal
• Algorithm Postorder(tree)
1.Traverse the left subtree, i.e., call
Postorder(left-subtree)
2.2. Traverse the right subtree, i.e., call
Postorder(right-subtree)
3.3. Visit the root.
Postorder Traversl
void printPostorder(struct node* node)
{
     if (node == NULL)
        return;
 
     // first recur on left subtree
     printPostorder(node->left);
 
     // then recur on right subtree
     printPostorder(node->right);
 
     // now deal with the node
     printf("%d ", node->data);
}
BST Shapes

 The order of supplying the data determines where it is placed in the BST , which
determines the shape of the BST
 Create BSTs from the same set of data presented each time in a different
order:
a) 17 4 14 19 15 7 9 3 16 10
b) 9 10 17 4 3 7 14 16 15 19
c) 19 17 16 15 14 10 9 7 4 3 can you guess this shape?
BST Operations: Removal

 removes a specified item from the BST and adjusts the tree
 uses a binary search to locate the target item:
 starting at the root it probes down the tree till it finds the target or reaches a leaf
node (target not in the tree)

removal of a node must not leave a ‘gap’ in the tree,


Removal in BST - Pseudocode

method remove (key)


I if the tree is empty return false
II Attempt to locate the node containing the target using the
binary search algorithm
if the target is not found return false
else the target is found, so remove its node:
Case 1: if the node has 2 empty subtrees
replace the link in the parent with null
Case 2: if the node has a left and a right subtree
- replace the node's value with the min/max value in the
left subtree
- delete the min/max node in the left subtree
Removal in BST - Pseudocode

Case 3:
Case 3.1:
if the node has no left child
- link the parent of the node
- to the right (non-empty) subtree
Case 3.2:
if the node has no right child
- link the parent of the target
- to the left (non-empty) subtree
Removal in BST: Example

Case 1: removing a node with 2 EMPTY SUBTREES

parent
7

cursor
5 9

4 6 8 10

7
Removing 4
replace the link in the parent
with null 5 9

6 8 10
Removal in BST: Example

Case 2: removing a node with 2 SUBTREES


- replace the node's value with the max value in the left subtree
- delete the max node in the left subtree
What other element
can be used as
Removing 7 replacement?
cursor
cursor

7 6

5 9 5 9

4 6 8 10 4 8 10
Removal in BST: Example

Case 3.1: removing a node with 1 EMPTY SUBTREE

the node has no left child:


link the parent of the node to the right (non-empty) subtree

parent
parent

7 7
cursor

5 9 cursor 5 9

6 8 10 6 8 10
Removal in BST: Example

Case 3.2: removing a node with 1 EMPTY SUBTREE

the node has no right child:


link the parent of the node to the left (non-empty) subtree

Removing 5
parent
parent

7 cursor 7
cursor

5 9 5 9

4 8 10 4 8 10
• Insert the following keys in empty binary
search tree:
17,13,21,10,24,23,15,27,4,11,25,16,26

Delete 4
Delete 10
Delete 13
Delete 17
Removal in BST: C code
struct node* deleteNode(struct bstnode* root, int data) else if (root->right == NULL)
        

{         {
            struct node *temp = root->left;
    if (root == NULL) return root;
     // If the key to be deleted is smaller than the root's key,     // then it lies in left
            free(root);
subtree             return temp;
    if (data < root->data)         }
        root->left = deleteNode(root->left, data);  
     // If the key to be deleted is greater than the root's key,     // then it lies in         // node with two children: Get the inorder
right subtree successor (smallest in the right subtree)
    else if (data> root->data)         struct node* temp = minValueNode(root->right);
        root->right = deleteNode(root->right, data);  
     // if key is same as root's key, then This is the node to be         // Copy the inorder successor's content to this
deleted node
    else         root->key = temp->key;
 
    {
        // Delete the inorder successor
        // node with only one child or no child         root->right = deleteNode(root->right, temp-
        if (root->left == NULL) >key);
        {     }
            struct node *temp = root->right;     return root;
            free(root); }
            return temp;
        }
        
Analysis of BST Operations

The complexity of operations get, insert and remove in BST is


O(h) , where h is the height.
O(log n) when the tree is balanced. The updating operations cause the
tree to become unbalanced.
The tree can degenerate to a linear shape and the operations will become
O (n)
Best Case
BST tree = new BST();

tree.insert ("E");
tree.insert ("C");
tree.insert ("D");
tree.insert ("A");
tree.insert ("H");
tree.insert ("F");
tree.insert ("K");

>>>> Items in advantageous order:


Output:
K
H
F
E
D
C
A
Worst Case
BST tree = new BST();
for (int i = 1; i <= 8; i++)
tree.insert (i);

Output: >>>> Items in worst order:


8
7
6
5
4
3
2
1
Random Case
tree = new BST ();
for (int i = 1; i <= 8; i++)
tree.insert(random());

Output: >>>> Items in random order:


X
U
P
O
H
F
B
Applications for BST
• Sorting with binary search trees
– Input: unsorted array
– Output: sorted array

• Algorithm ?
• Running time ?
Better Search Trees

Prevent the degeneration of the BST :


• A BST can be set up to maintain balance during updating
operations (insertions and removals)
• Types of ST which maintain the optimal performance:
– splay trees
– AVL trees
– 2-4 Trees
– Red-Black trees
– B-trees

You might also like