CS8391 Unit 3
CS8391 Unit 3
TREES ADT
5.1. INTRODUCTION
Tree is a non-linear data structures, (i.e. each element can be connected to more than
two adjacent elements) which represents hierarchical relationships between individual
elements. Naturally, tree grows upwards from the ground (root) into the air (Leaves). But
tree ADT grows downwards from the root to the leaves. This is a universally accepted way
of representing tree data structures.
Definition
Tree is a non-empty collection of nodes (N) & edges (N-1) that satisfies the
following requirements,
♣ It has a special data item referred as the root of the tree which not have parent.
♣ All remaining data items are partitioned into number of subsets, each of which itself
is a tree & are referred as Sub trees.
Each data item in a tree is referred as a node. Node is a basic structure of a tree & specifies
the information part of an element.
For example, consider the following tree with 8 nodes.
An important property of a tree is that there should be only one path exist
between any two nodes. If there is no path or more paths between some pair of
Note: nodes then we call the structure as a graph, not a tree.
4. Levels
The tree is organized in level to maintain the hierarchical relationship between
them. The entire tree structure is leveled in such a way that if a node is at level ‘n’, then its
children will be at level ‘n+1’. In general, the root node is always at level 1 then its
immediate children are at level 2 and so on. The child nodes of a parent are one level lower
than the parent node.
5. Root
A parent node in first level (i.e. 1th level) of tree is referred as a root node. A root
node does not have parent node.
Example: from the above tree ‘A’ is referred as the root node.
6. Branch
A Link between a parent node & its child node is also referred as a branch. All the
nodes in a tree, except the leaf node must have a branch.
Example: Node B has two branches namely E & F.
7. Siblings
The child node of a parent node is referred as siblings of the other child/children of
same parent.
Example: C & D are the siblings to ‘B’.
8. Subtree
It is a subset of tree that is itself a tree. If you remove the root then it becomes a
forest (i.e. subtrees are become a individual tree with its own root)
Example: If you remove the root ‘A’ then it becomes a forest with 3 trees namely B,
C & D.
9. Degree
The number of sub trees for a node is referred as its degree.
Example: The degree of root node ‘A’ is 3. The degree of ‘F’ is 1.
10. Ancestors
The ancestors of a node are all the nodes along the path from the root to that node.
The root node of the tree is the ancestor of the entire node in the tree.
Example: the ancestor of node ‘H’ is A, B & F
12. Height
Height of a tree is defined as the maximum level of any node in the tree. Height of a
node is a number of nodes from that node to the leaf at maximum level.
Example: The height of the tree is ‘4’. The height of the node ‘B’ is 3.
13. Depth
Depth and height of the tree is same. Depth of a node is a number of nodes from
root to that node.
Example: The depth of the tree is ‘4’. The depth of the node ‘F’ is 3.
One of the most important tree structures is the binary tree. A binary tree is a tree in
which a node should have either no child or not more than two children. Each node in the
binary tree has 2 subtrees,
♣ Left subtree: All the nodes to the left child of a given node in a binary tree.
♣ Right subtree: All the nodes to the right child of a given node in a binary
tree.
previous than last levels, where h is a height of binary tree. A node must be filled
from leftmost to rightmost in each level.
5.4.2.1.LINEAR REPRESENTATION
It is a simple way to implement a binary tree ADT. Binary tree can be represented
by using single dimensional array with the size of (2h) where ‘h’ is the height of a binary
tree. According to the property of binary tree, it should have maximum of 2h-1 node. So
that only, the array size is declared with respect to the height of the tree. Moreover, the 0th
index in array is not used for storing the binary tree elements. Therefore, the size of array
should be 2h instead of 2h-1.
For Example,
Step-3: The right child of nth index node is stored at the location (2n+1)th index.
Step-4: If there is no left or right child, the array location is left as empty.
For Example, consider the above binary tree structure. The array representation becomes,
Algorithm (searching a node which has a parent / right child / left child)
Step-1: Parent of ith index node is at (i/2)th index location, where i >1. If i=1 then it is the
root node of the tree which has no parent node.
Step-2: Left child of ith index node is at 2ith index position of array where 2i<=N where
N is the array size. If 2i>N then the ith index node has no left child.
Step-3: Right child of ith index node is at (2i+1)th position of array where (2i+1) <=N. If
(2i+1)>N then the ith index node has no right child.
To verify whether a parent or left or right child exists in a tree or not, the following
algorithm is used. For Example, take node ‘B’ which is stored in 3rd index position of
array.
✔ Left child node of B is in 3*2=6th index position in array (i.e.) node ‘C’.
✔ Right child node of B is in (3*2) +1=7th index in array (i.e.) node ‘D’.
✔ Left child node of C is in (6*2) =12th index, but 12>n value. Hence there is no
left child for a node C.
Even though we didn’t implement a full binary tree, we should allocate the
memory with the size 2h which if equal to the size of full binary tree. So the
Note: memory is wasted by using array data structure.
For Example,
♣ One of the most important operations performed on the binary tree is tree traversal.
Traversing a binary tree means moving through all the nodes in the binary tree,
visiting each node in the tree exactly once.
♣ In List ADT, the nodes are in natural order (i.e.) from first to last, hence traversal
follows the same order. However for trees, the nodes are not in order, hence we
have to follow different procedure for traversing all the nodes.
♣ One thing to be kept in mind, while traversing a binary tree, treats each node and its
sub trees in the same manner.
♣ The task performed while traversing a binary tree are,
✔ Visiting a node (denoted by the letter ‘O’ - root).
✔ Traversing the left sub tree (denoted by the letter ‘L’).
✔ Traversing the right sub tree (denoted by the letter ‘R’).
♣ Depending upon these three tasks, there are 6 possible combinations of traversals.
They are OLR, LOR, LRO, ORL, ROL, and RLO.
♣ These 6 traversals can be reduced to 3 combinations by adopting the convention,
that we always traverse the left sub tree before the right sub tree.
♣ Therefore the final possible combinations are OLR, LOR, and LRO. These are
referred as the “Preorder”, “Inorder” and “Postorder” traversals respectively.
5.5.1. PREORDER TRAVERSAL (OLR)
This process is continued until visiting all the nodes in the binary tree. After processing the
node, denote the node as visited. Preorder traversal leads to prefix expressions.
IMPLEMENTATION IN C
void Preorder(s *root)
{
if (root! =NULL)
{
printf (“%d\t”,root->data);
Preorder(root->left);
Preorder(root->right);
}
}
Inorder traversal of a binary tree always represents the element in ascending order, and
hence the process is referred as the sorting of binary tree
IMPLEMENTATION IN C
void Inorder(s *root)
{
if (root! =NULL)
{
Inorder(root->left);
printf (“%d\t”,root->data);
Inorder(root->right);
}
}
IMPLEMENTATION IN C
void Postorder(s *root)
{
if (root! =NULL)
{
Postorder(root->left);
Postorder(root->right);
printf (“%d\t”,root->data);
}
}
For example, consider the following binary trees to perform all types of traversal.
PROGRAM
/*Tree Traversal in BST*/
#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node *left,*right;
}*root=NULL;
typedef struct node s;
int insert(int);
void preorder(s *);
void postorder(s *);
void inorder(s *);
void searchitem(int);
void main()
{
int choice,no,x;
clrscr();
while(1)
{
printf("\n1.Insertion\n2.Preorder\n3.Inorder\n4.Postorder\n");
printf("5.searching\n6.Exit\nEnter U'r choice?");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
printf("Enter the Element to insert\n");
scanf("%d",&no);
x=insert(no);
if(x==1)
printf("Successfully Inserted\n");
else
printf("Error in insertion\n");
break;
}
case 2:
{
if(root!=NULL)
{
printf("\n Preorder elements are..\n");
preorder(root);
printf("\n");
}
else
{
printf("\n No elements to display\n");
}
break;
}
case 3:
{
if(root!=NULL)
{
printf("\n Inorder elements are..\n");
inorder(root);
printf("\n");
}
else
{
printf("\n No elements to display\n");
}
break;
}
case 4:
{
if(root!=NULL)
{
printf("\n Postorder elements are..\n");
postorder(root);
printf("\n");
}
else
{
printf("\n No elements to display\n");
}
break;
}
case 5:
{
printf("Enter the element to search?");
scanf("%d",&no);
searchitem(no);
break;
}
case 6:
exit(0); break;
default:
printf("Wrong Choice\n");
}
}
}
int insert(int x)
{
s *p,*prev,*ct;
p=(s *)malloc(sizeof(s));
if(p==NULL)
{
printf("out of memory\n");
return 0;
}
p->data=x;
p->left=NULL;
p->right=NULL;
if(root==NULL)
{
root=p;
return 1;
}
prev=NULL;
ct=root;
while(ct!=NULL)
{
prev=ct;
if(p->data<ct->data)
ct=ct->left;
else
ct=ct->right;
}
if(p->data<prev->data)
prev->left=p;
else
prev->right=p;
return 1;
}
if(p!=NULL)
{
inorder(p->left);
printf("%5d\t",p->data);
inorder(p->right);
}
}
ALGORITHM
Step-1: Process starts from the root node.
Step-2: Connect the parent to its left most child through an edge and connect the left most
child to all the nodes who are all the right siblings at the same level.
Step-3: Delete all the links from the parent node to its children except for the link to its
left most child.
Step-4: Repeat step-2 & 3 for each parent node in the general tree.
Step-5: Rotate the resultant tree to 450 for getting the clear view of binary
representation.
For example, from the tree above, node ‘B’ is the left child of ‘A’, which is
connected to all the right siblings (i.e. B-C-D-E). After that, delete the link from A-C, A-D
and A-E.
Let us consider the infix expression (a+b*c)+((d*e+f)*g). The expression tree for
that infix expression becomes,
Thus the expression tree for the infix expression (a+b)*(c*(d+e)) is in Stack at last.
5.8. CREATE A BINARY TREE USING INORDER AND PREORDER TRAVERSAL
A binary tree can be formed from the inputs of Inorder & Preorder traversal or
otherwise from the Inorder & Postorder traversal.
Algorithm
RebuildBinaryTree( )
1. Pick an element from Preorder traversal and denote that as a root. Increment a
Preorder Index Variable by one.
2. Create a new tree node with the data of root element. Say tNode.
3. Find the picked element’s index in Inorder. Say inIndex.
4. Call to RebuildBinaryTree for elements before inIndex and make the built tree as
left subtree of tNode.
5. Call to RebuildBinaryTree for elements after inIndex and make the built tree as right
subtree of tNode.
6. At last, the reconstructed tree is in tNode.
Thus the final binary tree was obtained from the input of Inorder & Preorder traversal.
The process of creating binary tree from the Inorder & Postorder is same as the
above representation whereas in Postorder the root is always at last i.e. after the
Note: left and right subtree nodes.
IMPLEMENTATION IN C
#define NULL 0
typedef struct btree
{
int data;
struct btree *left;
struct btree *right;
}node;
node *root;
void create(int,int [ ]);
void inorder(node *),preorder(node *);
void main( )
{
int i=0,p[30],in[30];
node *list;
clrscr();
printf("enter the preorder\n");
while(1) //getting array for preorder elements
{
scanf("%d",&p[i]);
i++;
if(p[i-1]==-99)
break;
}
}
else
{
if(i->right==NULL)
{
i->right=(node*)malloc(sizeof(node));
i=i->right;
i->data=key;
i->left=i->right=NULL;
break;
}
else
i=i->right;
}
}
}
int find(int t,int a[],int key)
{
int i,j;
for(i=0;a[i]!=-99;i++)
if(a[i]==t)
break;
for(j=0;j<i;j++)
if(a[j]==key)
return 1;
return 0;
}
void inorder(node *root)
{
if(root!=NULL)
{
inorder(root->left);
printf("%6d",root->data);
inorder(root->right);
}}
void preorder(node *root)
{ if(root!=NULL)
{
printf("%6d",root->data);
preorder(root->left);
preorder(root->right);
}
}
1. Creation of a BST
Creation of BST involves 3 processes.
1. Each node is a structure with 3 members. The memory is allocated for a node
dynamically using malloc( ) library function.
2. Create a node and assign NULL to the link field of newnode.
3. Read data for the newnode from user and store it in data field.
4. The creation of BST is done by repeatedly calling the insertion operation of BST.
2. Insertion of a node
One of the most primitive operations that can be done in a binary search tree is
insertion. The procedure for inserting a newnode in the existing binary search tree becomes,
Algorithm
1. Create a node by using malloc( ) and NULL to the link field of node. Get the
data from the user and assign it in data field of node.
2. Check whether the root node of BST is NULL or not.
3. If it is NULL, then consider the new node as the root node of BST. Otherwise
do next.
4. Compare the root node data with new node data for the following three
conditions.
a) If the content of data is equal to the root node data, then insertion
operation is terminated due to duplication of data.
b) If the content of the new node data is less than the root node data, then
check whether the left child of root node is NULL. If it is NULL then
insert the new node as the left child of root node (i.e. Root->
left=newnode). Otherwise consider the left child of root node become a
root node and repeat the process from step-4.
c) If the content of the new node data is greater than the root node data,
then check whether the right child of root node is NULL. If it is NULL
then insert the new node as the right child of root node (i.e. Root->
right=newnode). Otherwise consider the right child of root node
become a root node and repeat the process from step-4.
For example, create a BST for the following elements {7, 5, 10, 3, 6, 9, and 8}. Initially
BST is not yet created i.e. Root== NULL. So the first element 7 becomes the root node.
Pseudo Code
Tree-Insert (T, z)
y = NIL
x = root[T]
While x != NULL
do y = x
if key[z] < key[x] then
x = left[x]
else
x = right[x]
P[z] = y
if y = = NULL then
root[T] = z
else if key[z] < key[y] then
left[y] = z
else
right[y] = z
3. Deletion of a node
Another primitive operation that can be done in a BST is the deletion of a node. A
node can be deleted from the tree in 3 different places.
a) Deleting the leaf node
b) Deleting the node with only one child
c) Deleting the node with two children
a) Deleting the leaf node
Algorithm
Step-1: Search the parent node of the leaf node (which is going to be deleted) and
assign NULL to the link field of the leaf node.
Step-2: Release the memory for the deleted node by using free ( ) function.
Pseudo Code
Tree-Delete (T, z)
if left[z] = = NULL or right[z] = = NULL then
y=z
else
y = Tree-Successor(z)
if left[y] != NULL then
x = left[y]
else
x = right[y]
if x != NULL then
P[x] = P[y]
if P[y] = = NULL then
root[T] = x
else if y = left[P[y]] then
left[P[y]] = x
else
right[P[y]] = x
if y != z then
key[z] = key[y]
copy y’s data into z
return y
Pseudo Code
Tree-Search(x, k)
if x = = NULL or k = key[x] then
return x
if k < key[x] then
return Tree-Search(left[x], k)
else
return Tree-Search(right[x], k)
return x
IMPLEMENTATION IN C
/* Binary Serach Tree ADT */
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
#include<stdlib.h>
#define p printf
#define s scanf
typedef struct node
{
int data;
struct node *left,*right;
}tree;
tree *getnode( );
void readnode(tree *);
tree *create( );
void view(tree *btree, int level);
tree *insertnode(tree *btree, tree *temp);
void main( )
{
int choice;
tree *btree=NULL,*temp;
clrscr();
while(1)
{
p("\n1.create\n2.Display\nEnter u'r choice\n");
s("%d",&choice);
switch(choice)
{
case 1:
btree=NULL;
p("\ncreate a new tree\n");
btree=create();
break;
case 2:
if(btree!=NULL)
{
p("Binary tree is\n");
view(btree,1);
}
else
p("Tree is Empty\n");
break;
case 3:
exit(0);
break;
default:
break;
}
}
}
tree *getnode()
{
tree *newnode;
newnode=(tree *)malloc(sizeof(tree));
return newnode;
}
void readnode(tree *newnode)
{
p("Enter the Value\n");
s("%d",&newnode->data);
newnode->left=NULL;
newnode->right=NULL;
}
tree *create()
{
int ch=1;
tree *btree=NULL,*temp;
while(ch==1)
{
temp=getnode();
readnode(temp);
btree=insertnode(btree,temp);
p("2 u wish 2 continue press 1\n");
scanf("%d",&ch);
}
return btree;
}
tree *insertnode(tree *btree,tree *temp)
{
if(btree==NULL)
{
return temp;
}
else if(temp->data<btree->data)
{
btree->left=insertnode(btree->left,temp);
}
else if(temp->data>btree->data)
{
btree->right=insertnode(btree->right,temp);
}
else if(temp->data==btree->data)
{
p("\n data is alreaty exit\n");
return btree;
}
return btree;
}
void view(tree *btree, int level)
{
int k;
if(btree==NULL)
return;
view(btree->right,level+1);
p("\n");
for(k=0;k<level;k++)
p(" ");
p("%d",btree->data);
view(btree->left,level+1);
}
Sample I/O
1.create
2.Display
Enter u'r choice 1
create a new tree
Enter the Value 20
2 u wish 2 continue press 1 1
Enter the Value 10
2 u wish 2 continue press 1 1
Enter the Value 30
2 u wish 2 continue press 1 1
Enter the Value 5
2 u wish 2 continue press 1 1
Enter the Value 15
2 u wish 2 continue press 1 1
Enter the Value 25
2 u wish 2 continue press 1 1
Enter the Value 35
2 u wish 2 continue press 1 1
Enter the Value 40
2 u wish 2 continue press 1 2
1.create
2.Display
Enter u'r choice 2
Binary tree is
40
35
30
25
20
15
10
5
♣ In a threaded binary tree only two NULL pointers is used to indicate the start and
end pointer of binary tree where these nodes are first & last values in the Inorder
traversal of tree.
♣ It is also possible to discover the parent of a node, without explicit use of parent
pointer or a stack
♣ Threaded binary tree leads a more rapid linear traversal of binary tree rather than the
recursive traversal (i.e. during the traversal process, if it reaches the leaf node then it
should backtrack to its parent node and start the traversal process in different path.
So the traversal operations are performed only by making recursive functions. This
will be avoided when a binary tree is converted into a threaded binary tree).
Definition
A binary tree is threaded by making the entire right child pointers which has NULL
become points to the inorder successor of that node and all left child pointers which has
NULL would points to the inorder predecessor of that node. These valued are called as
Threads.
♣ If a node is a left child then its right link points to its parent or its right child.
♣ If a node is a right child then its left link points to its parent or its left child.
Example:
For the above binary tree, the Inorder traversal is [A, B, C, D, E, F, G, H, I]. Leaves
are A, C, E and H. A node which has NULL to its link field is {A, C, E, G, I, and H}
In threaded binary tree, Left Child of ‘A’ becomes NULL to indicate that A is a
starting node in Inorder traversal. Right Child of ‘I’ becomes NULL to indicate that I is an
end node in inorder traversal. Dashed edges indicate the threads.
✔ A is left child, so its right link points to its parent ‘B’.
✔ C is left child, so its right link points to its parent ‘D’.
✔ E is right child, so its left link points to its parent ‘D’.
Inorder Traversal for the above threaded binary tree is {1, 2, 3, 4, 5, 6, 7, 8, and
9} Initially N=1 and Visit-List = {1}. Further passes are,
✔ So Visit-List={1, 2, 3, 4, 5, 6, 7}
DEFINITION
AVL tree is also referred as Self-Adjusting binary search tree. It is a binary search
tree that satisfies the HB[1] property i.e. the heights of the left and right sub trees of a node
should differ by at most 1. For maintaining the HB[1] property, it keeps an addition piece of
information at each node referred as a “Balance Factor” which is denoted as BF(N) where
N is a node.
♣ Balance factor of a node is calculated by the difference between the height of its left
sub tree and the height of its right sub tree.
♣ In AVL trees, each node N should have a Balance Factor BF(N) either {-1, 0 or +1}.
AVL tree is called as a height balanced tree which means, it can be built to maintain
the balance within the left as well as its right subtrees.
♣ Any insertion or deletion of a node in AVL tree may violate the property of it (i.e.)
Balance Factor of any node should be greater than one. So, after each insertion or
deletion process the tree will be analyzed to see whether it violates the balance
condition or not. If it violates, then we need to reorganize the tree by a series of
“Rotations” to make it again balanced.
♣ Thus the insertion and deletion methods should be sensitive to maintaining this
balance factor of all nodes in AVL tree. The height of an AVL tree with N nodes
never exceeds (1.44 log N) and is typically much closer to log N.
♣ In N node - AVL tree, a node can be searched within O(log N) time. Insertion and
deletion operations in AVL tree can also be performed in O(log N) time.
For example,
From the above AVL tree {A, B, C, D, E, F, G, H, I, J and K} are elements and the
number represented in each node specifies the balance factor of that node. For example
BF(A)=0, BF(B)=1, BF(C)=0, BF(D)=(-1)
balanced or unbalanced after insertion or deletion of a node from tree. So depending upon
the balance factor of a node the rotation will be performed on the tree.
SINGLE ROTATION
DOUBLE ROTATION
Step-5: Identify the type of rotation which is performed to recover the AVL property
of a tree by traverse the insertion path only 2 steps downward from the pivot node.
(i.e.) visit only 2 nodes from the pivot node.
a) If the first node is a left child of pivot node say ‘K’ and second node is a left
child of Kth node then we have to perform L-L rotation.
b) If the first node is a right child of pivot node say ‘K’ and second node is a
right child of Kth node then we have to perform R-R rotation.
c) If the first node is a left child of pivot node say ‘K’ and second node is a
right child of Kth node then we have to perform L-R rotation.
d) If the first node is a right child of pivot node say ‘K’ and second node is a
left child of Kth node then we have to perform R-L rotation.
Step-6: Perform the corresponding rotation to recover a balanced tree which satisfies
the AVL Property.
No need to calculate the balance factor of nodes in AVL tree after performing the
rotation process. Surely it will satisfy the property of Binary search tree and
become balanced after a single or double rotation performed on an unbalanced
Note: tree.
IMPLEMENTATION IN C
typedef struct AVLNode *AVLTree, *Position;
struct AVLNode
{
int data;
AVLTree Left, Right;
int height;
}
static int Height(Position p)
{
if(P= =NULL) return -1;
else return P->height;
}
Insert(x, T)
{
if(T= = NULL)
{
T = malloc (size of (struct AVLNode) );
T -> data = h;
T-> height = 0;
T-> Left = T-> Right = NULL;
}
else if (x < T->data)
{
T-> Left = Insert(X, T->left);
if(height(T->Left) – height(T->Right) = = 2)
if(x < T->Left->data)
T = SingleRotateWithLeft( T );
else
T = DoubleRotateWithLeft( T );
}
else if(x > T->data)
{
T-> Right = Insert(X, T-> Right);
if(height(T-> Right) – height(T-> Left) = = 2)
if(x > T-> Right ->data)
T = SingleRotateWithRight( T );
else
T = DoubleRotateWithRight( T );
}
T->height = Max(height(T->Left), height(T->Right) ) + 1;
return T;
}
static Position SingleRotateWithLeft(Position K2)
{
Position K1;
K1 = K2->Left;
K2->Left = K1->Right;
K1->Right = K2;
K2->height = Max(Height(K2->Left), Height(K2->Right)) + 1;
K1->height = Max(Height(K1->Left), Height(K2->Right)) + 1;
return K1;
}
static Position SingleRotateWithRight(Position K2)
{
Position K1;
K1 = K2->Right;
K2->Right= K1->Left;
K1->Left = K2;
K2->height = Max(Height(K2->Right), Height(K2-> Left)) + 1;
K1->height = Max(Height(K1->Right), Height(K2-> Left)) + 1;
return K1;
}
static Position DoubleRotateWithLeft(Position K3)
{
K3->Left = SingleRotateWithRight(K3->Left);
return SingleRotateWithLeft(K3);
}
static Position DoubleRotateWithRight(Position K3)
{
K3->Right = SingleRotateWithLeft(K3-> Right);
return SingleRotateWithRight (K3);
}
An insertion into an AVL tree requires one single or double rotation to retain the
balance property of AVL tree. However deletion requires at most (logN) rotation, because
deletion of a node causes unbalance in the opposite subtree of the deleted node.
Rotation should be performed from the first node which causes unbalance on tree
and then moving upward to the root of the tree. Experimentally, it has been found that 50%
of insertion operations do not require rotation process or rebalancing but 75% of deletion
oprations do not require rebalancing.
For example,
PSEUDO CODE
Parent(i)
{
return (i/2)
}
Left(i)
{
return (2i)
}
Right(i)
{
return (2i+1)
}
ALGORITHM
Step-1: Allocate the size of array by 2H where H represents the height of the tree.
Step-2: Sequentially insert the input elements onto the array of HeapSize, only after
incrementing HeapSize by 1. HeapSize refers the number of nodes in heap tree and
initially it is 0.
Step-3: Take an index (HeapSize/2) & say ‘X’ where X is the index of first parent node
in rightmost place of highest level in tree.
Step-4: Call to Heapify process by passing X.
Step-5: Decrement X by one and repeat from step 4 until X is equal to 1 (i.e.) root node
HEAPIFY ALGORITHM
Step-1: Compare the key of index X with its key of left and right child, if the key of X is
greater than the children then terminate the process (i.e.) already the tree satisfy the
heap properties.
Step-2: If any one of the child has greater key than key of X then take the index of
largest key say ‘L’.
Step-3: If L is not equal to X then exchange the key of L and X as well as assign L to X
and Repeat the steps from 4 until X has no child.
PSEUDO CODE
Build-Max-Heap (A)
HeapSize[A] = length[A]
for i=floor(length(A/2)) downto 1 // floor returns the integer part of float i.e. the value
before ‘.’
do Max-Heapify(A, i)
Build-Min-Heap (A)
HeapSize[A] = length[A]
Max-Heapify(A, i)
L=Left(i)
R=Right(i);
if L <= HeapSize[A] and A[L] > A[i] then
largest = L
else
largest = i
if R <= HeapSize[A] and A[R] > A[largest] then
largest = R
if largest != i then
Exchange A[i], A[largest]
Max-Heapify(A, largest)
Min-Heapify(A, i)
L=Left(i)
R=Right(i);
if L <= HeapSize[A] and A[L] < A[i] then
smallest = L
else
smallest = i
if R <= HeapSize[A] and A[R] < A[smallest] then
smallest = R
if smallest!= i then
Exchange A[i], A[smallest]
Min-Heapify(A, smallest)
For example, consider the input sequence {7, 15, 8, 12 and 20} to build a Max-heap with
the height of 3.
Step 1: form a tree for the given input sequence.
When X = 1
PSEUDO CODE
Max-Heap-Insert(A, key)
HeapSize = HeapSize + 1
A[HeapSize] = key
I = HeapSize
while I >1 and A[Parent(I)] < A[I]
do exchange A[Parent(I)], A[I]
I = Parent(I)
Min-Heap-Insert(A, key)
HeapSize = HeapSize + 1
A[HeapSize] = key
I = HeapSize
while I >1 and A[Parent(I)] > A[I]
do exchange A[Parent(I)], A[I]
I = Parent(I)
ALGORITHM
Step-1: Check the HeapSize is less than one or not. If it is less than one then show error
message as “Heap underflow” and terminate the process
Step-2: Otherwise, assign the array of first element as Max (or Min for minimum
element) and assign key of HeapSize to the key of first element.
Step-3: Decrease the HeapSize by one and make a call to Max-Heapify(A, 1) or
Min-Heapify(A, 1)
Step-4: Return the Max (or Min) is an Extracted node from a heap.
PSEUDO CODE
Heap-Extract-Max(A)
Heap-Extract-Min(A)
if HeapSize < 1 then
Error “Heap Underflow”
Min = A[1]
A[1] = A[HeapSize]
HeapSize = HeapSize – 1
Min-Heapify(A, 1)
return Min
For example, extract the maximum element from the following Max-Heap
PSEUDO CODE
MaxHeap-Delete-Node(A, D)
A[D] = A[1] + 1
while (D < 1)
Exchange A[Parent(D)], A[D]
D = Parent(D)
Heap-Extract-Max(A)
MinHeap-Delete-Node(A, D)
A[D] = A[1] + 1
while (D < 1)
Exchange A[Parent(D)], A[D]
D = Parent(D)
Heap-Extract-Min(A)
For example, delete an element 15 from the following heap tree
1. HEAP SORT
This is a one type of sorting technique which requires a less execution time
compare to Insertion sort & Selection sort techniques. The best, average and worst case
running time to perform sorting is O(Log N) where N is a number of elements to sort.
PSEUDO CODE
HeapSort-Descending(A)
Build-Max-Heap(A)
i = length[A]
while i <= 2
do Exchange A[i], A[1]
HeapSize = HeapSize – 1
Max-Heapify(A, 1)
HeapSort-Ascending(A)
Build-Min-Heap(A)
i = length[A]
while i <= 2
do Exchange A[i], A[1]
HeapSize = HeapSize – 1
Min-Heapify(A, 1)
2. PRIORITY QUEUE
It is a type of Queue ADT. The operations of priority queue are insertion and deletion
which is worked based on the priority of each element. Implementation of priority queue is
done by the heap representation which takes O(Log N) time to execute insertion or
deletion.
B - Trees
In a binary search tree, AVL Tree, Red-Black tree etc., every node can have only one value
(key) and maximum of two children but there is another type of search tree called B-Tree in
which a node can store more than one value (key) and it can have more than two children.
B-Tree was developed in the year of 1972 by Bayer and McCreight with the name Height
Balanced m-way Search Tree. Later it was named as B-Tree.
B-Tree is a self-balanced search tree with multiple keys in every node and more than
two children for every node.
Here, number of keys in a node and number of children for a node is depend on the order of
the B-Tree. Every B-Tree has order.
For example, B-Tree of Order 4 contains maximum 3 key values in a node and maximum 4
children for a node.
Example
children that node has. In a B-Ttree, the search operation is performed with O(log n) time
complexity. The search operation is performed as follows...
Example
Construct a B-Tree of Order 3 by inserting numbers from 1 to 10.