Module 4.3

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 38

BINARY SEARCH TREES

BINARY SEARCH TREES


• A binary search tree, also known as an ordered binary tree, in which the nodes
are arranged in an order.
• In a binary search tree, all the nodes in the left sub-tree have a value less than
that of the root node. Correspondingly, all the nodes in the right sub-tree have a
value either equal to or greater than the root node.
• The same rule is applicable to every sub-tree in the tree.
• Note that a binary search tree may or may not contain duplicate values,
depending on its implementation.
• Since the nodes in a binary search tree are ordered, the time needed to search
an element in the tree is greatly reduced.
• Whenever we search for an element, we do not need to traverse the entire tree.
At every node, we get a hint regarding which sub-tree to search in.
 Example: in the given tree, if we have to search
for 29, then we know that we have to scan only
the left sub-tree.
 If the value is present in the tree, it will only be
in the left sub-tree, as 29 is smaller than 39 (the
root node’s value).
 The left sub-tree has a root node with the value
27. Since 29 is greater than 27, we will move to
the right sub-tree, where we will find the
element.
 Thus, the average running time of a search
operation is O(log2 n).
 Binary search trees also speed up the insertion
and deletion operations.
Due to its efficiency in searching elements, binary search trees are widely used in
dictionary problems where the code always inserts and searches the elements that are
indexed by some key value.

State whether the binary trees are binary search trees or not.
• Create a binary search tree using the following data elements: 45, 39, 56,
12, 34, 78, 32, 10, 89, 54, 67, 81
• The first value in the given list is always the root
Problem
1. Create a binary search tree with the input given below:
98, 2, 48, 12, 56, 32, 4, 67, 23, 87, 23, 55, 46

2. Create a binary search tree


20,30,4,14,6,7,9,52,29

6
OPERATIONS ON BINARY SEARCH TREES
Operations on Binary Search Tree are:
1. Searching for a Node in a Binary Search Tree
2. Inserting a New Node in a Binary Search Tree
3. Deleting a Node from a Binary Search Tree
Case 1: Deleting a Node that has No Children
Case 2: Deleting a Node with One Child
Case 3: Deleting a Node with Two Children
4. Determining the Height of a Binary Search Tree
5. Determining the Number of Nodes
Determining the Number of Internal Nodes
Determining the Number of External Nodes
6. Finding the Mirror Image of a Binary Search Tree
7. Deleting a Binary Search Tree
8. Finding the Smallest Node in a Binary Search Tree
9. Finding the Largest Node in a Binary Search Tree
Searching for a Node in a Binary Search Tree

• In Step 1, we check if the value stored at


the current node of TREE is equal to VAL
or if the current node is NULL, then we
return the current node of TREE.

• Otherwise, if the value stored at the


current node is less than VAL, then the
algorithm is recursively called on its right
sub-tree, else the algorithm is called on
its left sub-tree.
Inserting a New Node in a Binary Search Tree
• If the current node is NULL
• Return a new node created with the specified value.
• If the value is less than the key of the current node:
• Recursively call insertNode with the left subtree of the current node and the
value.
• Update the left child of the current node with the result of the recursive call.
• If the value is greater than the key of the current node:
• Recursively call insertNode with the right subtree of the current node and the
value.
• Update the right child of the current node with the result of the recursive call.
• Return the current node (the root of the modified tree).
Create and Inserting a New Node in a BST
• Insert function first checks if the current node
of TREE is NULL. If it is NULL, the
algorithm simply adds the node, else it looks at
the current node’s value and then recurs down
the left or right sub-tree.
• If the current node’s value is less than that of
the new node, then the right sub-tree is
traversed, else the left sub-tree is traversed.
• The insert function continues moving down
the levels of a binary tree until it reaches a leaf
node.
• The new node is added by following the rules
of the binary search trees. That is, if the new
node’s value is greater than that of the parent
node, the new node is inserted in the right sub-
tree, else it is inserted in the sub-tree.
int main() case 2:
#include <stdio.h>
{ printf("\nPre-order Traversal: \n");
#include <stdlib.h>
int option, val; preorderTraversal(root);
#include <malloc.h>
struct node *root=NULL; break;
while(1) case 3:
struct node
{ printf("\nIn-order Traversal : \n");
{
printf("\n 1. Insert Element"); inorderTraversal(root);
int data;
printf("\n 2. Preorder Traversal");
struct node *left; break;
printf("\n 3. Inorder Traversal");
struct node *right; case 4:
printf("\n 4. Postorder Traversal");
}; printf("\nIn-order Traversal : \n");
printf("\n 5. Exit");
postorderTraversal(root);
printf("\nEnter your option :\n ");
struct node *root; break;
scanf("%d", &option);
switch(option) case 5:
struct node *insertnode(struct node *, { exit(0);
int); }
case 1: printf("\n Enter Value :
void preorderTraversal(struct node *); "); }
void inorderTraversal(struct node *); scanf("%d", &val); return 0;
void postorderTraversal(struct node root = insertnode(root, val); }
*);
Inserting a new node in a BST while(ptr!=NULL)
struct node* insertnode(struct node *root, int val) {
{ temp=ptr;
struct node *new_node, *ptr, *temp; if(val < (ptr ->data))
new_node = (struct node*)malloc(sizeof(struct node));
ptr=ptr ->left;
new_node -> data = val; else
new_node ->left = NULL; ptr = ptr ->right;
new_node ->right = NULL; }
if(root==NULL) if(val < (temp ->data))
root= new_node; temp ->left = new_node;
else else
{ temp ->right = new_node;
ptr=root; }
return root;
}
BST Traversal
void preorderTraversal(NODE *root) void postorderTraversal(NODE *root)
{ {
if(root != NULL) if(root != NULL)
{ {
printf("%d\t", root–>data); postorderTraversal(root->left);
preorderTraversal(root–>left); postorderTraversal(root->right);
preorderTraversal(root–>right); printf("%d\t", root->data);
} }
} }
void inorderTraversal(NODE *root)
{
if(root != NULL)
{
inorderTraversal(root->left);
printf("%d\t", root->data);
inorderTraversal(root->right);
}
}
Deleting a node from a BST

The delete function deletes a node from the binary search tree.
Case 1: Deleting a node that has no children
Case 2: Deleting a node with one child
Case 3: Deleting a node with 2 children
Case 1: Deleting a Node that has No Children
• Look at the binary search tree given in Fig. If we have to delete node 78, we
can simply remove this node without any issue.
• This is the simplest case of deletion.
Case 2: Deleting a Node with One Child
• In this case, the node’s child is set
as the child of the node’s parent.
• In other words, replace the node
with its child.
• Now, if the node is the left child of
its parent, the node’s child becomes
the left child of the node’s parent.
• Correspondingly, if the node is the
right child of its parent, the node’s
child becomes the right child of the
node’s parent.
Case 3: Deleting a Node with Two Children
• In this case, replace the node’s value with its in-order predecessor (largest value in the
left sub-tree) or in-order successor (smallest value in the right sub-tree).
• The in-order predecessor or the successor can then be deleted using any of these cases.
• Look at the Fig. see how deletion of node with value 56 is handled with its in-order
predecessor.
This deletion could also be handled by replacing node 56 with its
in-order successor, as shown in Fig.
• In Step 1 of the algorithm, first check if TREE=NULL, because
if it is true, then the node to be deleted is not present in the tree.
• If that is not the case, then we check if the value to be deleted is
less than the current node’s data. In case the value is less, we
call the algorithm recursively on the node’s left sub-tree,
otherwise the algorithm is called recursively on the node’s right
sub-tree.
• Note that if we have found the node whose value is equal to
VAL, then we check which case of deletion it is.
• If the node to be deleted has both left and right children, then we
find the in-order predecessor of the node by calling
findLargestNode(TREE ->LEFT) and replace the current node’s
value with that of its in-order predecessor.
• Then, we call Delete(TREE -> LEFT, TEMP -> DATA) to delete
the initial node of the in-order predecessor. Thus, we reduce the
case 3 of deletion into either case 1 or case 2 of deletion
• If the node to be deleted does not have any child, then we simply
set the node to NULL.
• Last but not the least, if the node to be deleted has either a left or
a right child bu not both, then the current node is replaced by its
Determining the height of a BST
• In order to determine the height of a binary search tree, we
calculate the height of the left sub-tree and the right sub-tree.
Whichever height is greater, 1 is added to it.
• For example, if the height of the left sub-tree is greater than that of
the right sub-tree, then 1 is added to the left sub-tree, else 1 is
added to the right sub-tree.
• Look at Fig. Since the height of the right sub-tree is greater than
the height of the left sub-tree, the height of the tree = height (right
sub-tree) + 1= 2 + 1 = 3.
• Figure shows a recursive algorithm that
determines the height of a binary search
tree.
• In Step 1 of the algorithm, first check if the
current node of the TREE = NULL. If the
condition is true, then 0 is returned to the
calling code.
• Otherwise, for every node, we recursively
call the algorithm to calculate the height of
its left sub-tree as well as its right sub-tree.
• The height of the tree at that node is given
by adding 1 to the height of the left sub-tree
or the height of right sub-tree, whichever is
greater.
Determining the Number of Nodes

• It is similar to determining its height.


• To calculate the total number of elements/nodes in the tree, we count the
number of nodes in the left sub-tree and the right sub-tree.
• Number of nodes = totalNodes(left sub–tree) + totalNodes(right sub–tree)
+1
• Consider the tree given in Fig. The total number of nodes in the tree can be
calculated as:
• Total nodes of left sub–tree = 1
• Total nodes of left sub–tree = 5
• Total nodes of tree = (1 + 5) + 1
• For every node, we recursively call the
algorithm on its left sub-tree as well as the
right sub-tree.

• The total number of nodes at a given node


is then returned by adding 1 to the number
of nodes in its left as well as right sub-tree.

• However if the tree is empty, that is TREE


= NULL, then the number of nodes will be
zero.
int totalNodes(NODE *root)
{
if(root==NULL)
return 0;
else
return(totalNodes(root–>left) + totalNodes(root–>right) + 1);
}
Determining the Number of Internal Nodes

• To calculate the total number of internal nodes or non-leaf nodes, we count the
number of internal nodes in the left sub-tree and the right sub-tree and add 1
to it (1 is added for the root node).
• Number of Internal Nodes= totalInternalNodes(left sub–tree) +
totalInternalNodes(right sub–tree) + 1
• Consider the tree given in Fig. The total number of internal nodes in the tree
can be calculated as:
• Total internal nodes of left sub–tree = 0
• Total internal nodes of right sub–tree = 3
• Total internal nodes of tree = (0 + 3) + 1 = 4
• For every node, we recursively call the
algorithm on its left subtree as well as
the right sub-tree.
• The total number of internal nodes at
a given node is then returned by
adding internal nodes in its left as
well as right sub-tree.
• However, if the tree is empty, that is
TREE = NULL, then the number of
internal nodes will be zero.
• Also if there is only one node in the
tree, then the number of internal
nodes will be zero.
Determining the Number of External Nodes
• To calculate the total number of external nodes or leaf nodes, we add the
number of external nodes in the left sub-tree and the right sub-tree.
• However if the tree is empty, that is TREE = NULL, then the number of external
nodes will be zero.
• But if there is only one node in the tree, then the number of external nodes will
be one.
• Number of external nodes = totalExternalNodes(left sub–tree) +
totalExternalNodes (right sub–tree).
• The total number of external nodes in the given tree can be calculated as:
• Total external nodes of left sub–tree = 1
• Total external nodes of left sub–tree = 2
• Total external nodes of tree = 1 + 2 = 3
• For every node, we recursively call the
algorithm on its left sub-tree as well as
the right sub-tree.
• The total number of external nodes at a
given node is then returned by adding
the external nodes in its left as well as
right sub-tree.
• However if the tree is empty, that is
TREE = NULL, then the number of
external nodes will be zero.
• Also if there is only one node in the tree,
then there will be only one external
node (that is the root node).
Finding the Mirror Image of a Binary Search Tree

• Mirror image of a binary search tree is


obtained by interchanging the left sub-tree
with the right sub-tree at every node of the
tree.
• For example, given a tree T, the mirror image of
T can be obtained as T’.
• a recursive algorithm to obtain the mirror
image of a binary search tree.
• In the algorithm, if TREE != NULL, that is if the
current node in the tree has one or more
nodes, then the algorithm is recursively called
at every node in the tree to swap the nodes in
its left and right sub-trees.
Deleting a Binary Search Tree

• To delete/remove an entire binary search


tree from the memory, we first delete the
elements/nodes in the left sub-tree and
then delete the nodes in the right sub-
tree.
• The algorithm shown in Fig. gives a
recursive procedure to remove the binary
search tree
Finding the Smallest Node in a Binary Search Tree

• The very basic property of the binary search


tree states that the smaller value will occur
in the left sub-tree.
• If the left sub-tree is NULL, then the value
of the root node will be smallest as
compared to the nodes in the right sub-tree.
• So, to find the node with the smallest value,
we find the value of the leftmost node of the
left sub-tree.
• The recursive algorithm to find the smallest
node in a binary search tree is shown in Fig.
Finding the Largest Node in a Binary Search Tree

• To find the node with the largest


value, we find the value of the
rightmost node of the right subtree.
• However, if the right sub-tree is
empty, then the root node will be the
largest value in the tree.
• The recursive algorithm to find the
largest node in a binary search tree is
shown in Fig.
Write a C program to find the number of leaf nodes and print all root to leaf paths
of BST.
int main() case 2:
#include <stdio.h> { printf("\nTotal leaf node = %d
#include <stdlib.h> int option, val; \n",totalLeafNodes(root) );
#include <malloc.h> NODE *root=NULL; break;
while(1) case 3: printallpaths(root);
typedef struct node { break;
{ printf("\n 1. Insert Element");
case 4:exit(0);
int data; printf("\n 2. Count Leaf nodes");
}} return 0; }
struct node *left; printf(“\n 3. Print all paths”);
struct node *right; printf("\n 4. Exit");
}NODE; printf("\nEnter your option :\n ");
scanf("%d", &option);
NODE *root; switch(option)
{
NODE *insertnode(NODE *, int); case 1:printf("\n Enter Value : ");
int totalLeafNodes(NODE *); scanf("%d", &val);
void printallpaths(NODE *); root = insertnode(root, val);
break;
int totalLeafNodes(NODE *root)
{
if(root==NULL)
return 0;
else if((root–>left==NULL) && (root–>right==NULL))
{
printf("\n%d ", root->data);
return 1;
}
else
return (totalLeafNodes(root–>left) + totalLeafNodes(root–>right));
}
void printPathsRecur(NODE *root, int path[], int pathlen)
{
int i;
NODE *temp;
if (root==NULL)
return;
void printallpaths(NODE *root) temp = root; // append this node to the path array
{ path[pathlen] = temp->data;
int path[100]; pathlen++;
printPathsRecur(root, path, 0); if (temp->left==NULL && temp->right==NULL)
{ // it's a leaf, so print the path that lead to here
} for (i=0; i<pathlen; i++)
printf("%d ", path[i]);
printf("\n");
}
else
{ // otherwise try both subtrees
printPathsRecur(temp->left, path, pathlen);
printPathsRecur(temp->right, path, pathlen);
}
}
Write a C program to construct a binary tree of integers and also display
elements in the tree using Inorder, Preorder and Postorder traversals.

Write a C program to print all root to leaf paths of BST

You might also like