The AVL tree is a self-balancing
binary search tree in which the heights of the two child sub-trees of any node
differ by at most one. If at any time they differ by more than one, rebalancing
is done by one or more tree rotations to restore this property. Basic
operations such as lookup, insertion, deletion all take O(log n) time in both
the average and worst cases, where n is the number of nodes in the tree prior
to the operation.
(graphically represented):
Source Code of AVL tree:
Method 1:
#include
<stdio.h>
#include
<stdlib.h>
struct AVLTree_Node {
int data, bfactor;
struct AVLTree_Node
*link[2];
};
struct AVLTree_Node
*root = NULL;
struct AVLTree_Node *
createNode(int data) {
struct AVLTree_Node
*newnode;
newnode = (struct
AVLTree_Node *)malloc(sizeof (struct AVLTree_Node));
newnode->data = data;
newnode->bfactor =
0;
newnode->link[0] =
newnode->link[1] = NULL;
return newnode;
}
void insertion (int
data) {
struct AVLTree_Node
*bf, *parent_bf, *subtree, *temp;
struct AVLTree_Node
*current, *parent, *newnode, *ptr;
int res = 0,
link_dir[32], i = 0;
if (!root) {
root =
createNode(data);
return;
}
bf = parent_bf =
root;
/* find the location
for inserting the new node*/
for (current = root;
current != NULL; ptr = current, current = current->link[res]) {
if (data ==
current->data) {
printf("\nDuplicates
Are Not Allowed!\n");
return;
}
res = (data >
current->data) ? 1 : 0;
parent = current;
if
(current->bfactor != 0) {
bf = current;
parent_bf = ptr;
i = 0;
}
link_dir[i++] = res;
}
/* create the new
node */
newnode =
createNode(data);
parent->link[res]
= newnode;
res = link_dir[i =
0];
/* updating the
height balance after insertion */
for (current = bf;
current != newnode; res = link_dir[++i])
{
if (res == 0)
current->bfactor--;
else
current->bfactor++;
current =
current->link[res];
}
/* right sub-tree */
if (bf->bfactor ==
2) {
printf("bfactor
= 2\n");
temp =
bf->link[1];
if (temp->bfactor
== 1) {
subtree = temp;
bf->link[1] =
temp->link[0];
temp->link[0] =
bf;
temp->bfactor =
bf->bfactor = 0;
}
else {
subtree =
temp->link[0];
temp->link[0] =
subtree->link[1];
subtree->link[1] =
temp;
bf->link[1] =
subtree->link[0];
subtree->link[0] =
bf;
/* update balance
factors */
if
(subtree->bfactor == -1) {
bf->bfactor = 0;
temp->bfactor = 1;
}
else if
(subtree->bfactor == 0) {
bf->bfactor = 0;
temp->bfactor = 0;
}
else if
(subtree->bfactor == 1) {
bf->bfactor = -1;
temp->bfactor = 0;
}
subtree->bfactor =
0;
}}
/* left sub-tree */
else if
(bf->bfactor == -2) {
temp =
bf->link[0];
if (temp->bfactor
== -1) {
subtree = temp;
bf->link[0] =
temp->link[1];
temp->link[1] =
bf;
temp->bfactor =
bf->bfactor = 0;
}
else {
subtree =
temp->link[1];
temp->link[1] =
subtree->link[0];
subtree->link[0] =
temp;
bf->link[0] = subtree->link[1];
subtree->link[1] =
bf;
/* update balance
factors */
if
(subtree->bfactor == -1) {
bf->bfactor = 1;
temp->bfactor = 0;
}
else if
(subtree->bfactor == 0) {
bf->bfactor = 0;
temp->bfactor = 0;
}
else if
(subtree->bfactor == 1) {
bf->bfactor = 0;
temp->bfactor =
-1;
}
subtree->bfactor =
0;
}}
else {
return;
}
if (bf == root) {
root = subtree;
return;
}
if (bf !=
parent_bf->link[0]) {
parent_bf->link[1]
= subtree;
}
else {
parent_bf->link[0]
= subtree;
}
return;
}
void deletion(int
data) {
int link_dir[32], res
= 0, i = 0, j = 0, index = 0;
struct AVLTree_Node
*ptr[32], *current, *temp, *x, *y, *z;
current = root;
if (!root) {
printf("\nAVL
Tree Was Not Found!");
return;
}
if ((root->data ==
data) && (root->link[0] == NULL)
&&
(root->link[1] == NULL)) {
free(root);
root = NULL;
return;
}
/* search the node to
delete */
while (current !=
NULL) {
if (current->data
== data)
break;
res = data >
current->data ? 1 : 0;
link_dir[i] = res;
ptr[i++] = current;
current = current->link[res];
}
if (!current) {
printf("\nGiven
Data Was Not Found!");
return;
}
index = link_dir[i -
1];
temp =
current->link[1];
/* delete the node
from the AVL tree - similar to BST deletion */
if
(current->link[1] == NULL) {
if (i == 0) {
temp =
current->link[0];
free(current);
root = temp;
return;
}
else {
ptr[i -
1]->link[index] = current->link[0];
}}
else if
(temp->link[0] == NULL) {
temp->link[0] =
current->link[0];
temp->bfactor =
current->bfactor;
if (i > 0) {
ptr[i-1]->link[index]
= temp;
}
else {
root = temp;
}
link_dir[i] = 1;
ptr[i++] = temp;
}
else {
/* delete node with
two children */
j = i++;
while (1) {
link_dir[i] = 0;
ptr[i++] = temp;
x = temp->link[0];
if (x->link[0] ==
NULL)
break;
temp = x;
}
x->link[0] =
current->link[0];
temp->link[0] =
x->link[1];
x->link[1] =
current->link[1];
x->bfactor =
current->bfactor;
if (j > 0) {
ptr[j -
1]->link[index] = x;
}
else {
root = x;
}
link_dir[j] = 1;
ptr[j] = x;
}
free(current);
for (i = i - 1; i
>= 0; i = i--) {
x = ptr[i];
if (link_dir[i] == 0)
{
x->bfactor++;
if (x->bfactor ==
1) {
break;
}
else if
(x->bfactor == 2) {
y = x->link[1];
if (y->bfactor ==
-1) {
/* double rotation -
(SR right + SR left) */
z = y->link[0];
y->link[0] =
z->link[1];
z->link[1] = y;
x->link[1] =
z->link[0];
z->link[0] = x;
/* update balance
factors */
if (z->bfactor ==
-1) {
x->bfactor = 0;
y->bfactor = 1;
}
else if
(z->bfactor == 0) {
x->bfactor = 0;
y->bfactor = 0;
}
else if
(z->bfactor == 1) {
x->bfactor = -1;
y->bfactor = 0;
}
z->bfactor = 0;
if (i > 0) {
index = link_dir[i -
1];
ptr[i -
1]->link[index] = z;
}
else {
root = z;
}}
else {
/* single rotation
left */
x->link[1] =
y->link[0];
y->link[0] = x;
if (i > 0) {
index = link_dir[i -
1];
ptr[i -
1]->link[index] = y;
}
else {
root = y;
}
/* update balance
factors */
if (y->bfactor ==
0) {
x->bfactor = 1;
y->bfactor = -1;
break;
}
else {
x->bfactor = 0;
y->bfactor = 0;
}}}}
else {
x->bfactor--;
if (x->bfactor ==
-1) {
break;
}
else if
(x->bfactor == -2) {
y = x->link[0];
if (y->bfactor == 1) {
/* double rotation -
(SR right + SR left) */
z = y->link[1];
y->link[1] =
z->link[0];
z->link[0] = y;
x->link[0] =
z->link[1];
z->link[1] = x;
/* update balance
factors */
if (z->bfactor ==
-1) {
x->bfactor = 1;
y->bfactor = 0;
}
else if
(z->bfactor == 0) {
x->bfactor = 0;
y->bfactor = 0;
}
else if
(z->bfactor == 1) {
x->bfactor = 0;
y->bfactor = -1;
}
z->bfactor = 0;
if (i > 0) {
index = link_dir[i -
1];
ptr[i -
1]->link[index] = z;
}
else {
root = z;
}}
else {
/* single rotation
right */
x->link[0] =
y->link[1];
y->link[1] = x;
if (i <= 0) {
root = y;
}
else {
index = link_dir[i -
1];
ptr[i -
1]->link[index] = y;
}
/* update balance
factors */
if (y->bfactor ==
0) {
x->bfactor = -1;
y->bfactor = 1;
break;
}
else {
x->bfactor = 0;
y->bfactor = 0;
}}}}}}
void
searchElement(int data) {
int flag = 0, res =
0;
struct AVLTree_Node
*node = root;
if (!node) {
printf("\nAVL
Tree Was Not Found!");
return;
}
while (node != NULL)
{
if (data ==
node->data) {
printf("\nOk! %d
Present In AVL Tree.\n", data);
flag = 1;
break;
}
res = data >
node->data ? 1 : 0;
node =
node->link[res];
}
if (!flag)
printf("\nGosh!
%d Was Not Found In AVL Tree.\n", data);
return;
}
void
inorderTraversal(struct AVLTree_Node *myNode) {
if (myNode) {
inorderTraversal(myNode->link[0]);
printf("%d ", myNode->data);
inorderTraversal(myNode->link[1]);
}
return;
}
int main() {
int key, ch;
while (1) {
printf("\n\t1.
Insertion\t2. Deletion\n");
printf("\t3.
Searching\t4. Traversal\n");
printf("\t5.
Exit \n\nEnter Your Choice: ");
scanf("%d",
&ch);
switch (ch) {
case 1:
printf("\nEnter
The Value: ");
scanf("%d",
&key);
insertion(key);
break;
case 2:
printf("\nEnter
The Value To Delete: ");
scanf("%d",
&key);
deletion(key);
break;
case 3:
printf("\nEnter
The Value: ");
scanf("%d",
&key);
searchElement(key);
break;
case 4:
printf("\nThe
Current AVL Tree: ");
inorderTraversal(root);
printf("\n");
break;
case 5:
exit(0);
default:
printf("\nWrong
Option!");
break;
}
printf("\n");
}
return 0;
}
Method 2:
#include<stdio.h>
#include<malloc.h>
typedef struct bst {
int info;
int height;
struct bst *left;
struct bst *right;
} NODE;
typedef NODE* ROOT;
// For setting and
updating the height of the tree at each node
int set_height(ROOT
r) {
int left_h = -1;
int right_h = -1;
if(r->left)
left_h =
r->left->height;
if(r->right)
right_h =
r->right->height;
if(left_h >=
right_h)
r->height =
left_h+1;
else
r->height =
right_h+1;
return r->height;
}
int compare(int
data1, int data2) {
if(data1<data2)
return -1;
if(data1>data2)
return 1;
else
return 0;
}
// Doing Left-Left
rotation
void rotate_LL(ROOT
*r) {
NODE *r1, *r2 =
*r,*t1,*t2,*t3;
r1 = r2->left;
t1 = r1->left;
t2 = r1->right;
t3 = r2->right;
// Actual rotation
happens here
r1->right = r2;
r2->left = t2;
// Update the r1 , r2
height
set_height(r1);
set_height(r2);
*r = r1;
}
// Doing Right-Left
rotation
void rotate_RL(ROOT
*r) {
NODE *r1,*r2,
*r3=*r,*t1,*t2,*t3,*t4;
r1 = r3->left;
r2 = r1->right;
t2 = r2->left;
t3 = r2->right;
// Actaul rotation
happens here
r1->right = t2;
r3->left = t3;
r2->left = r1;
r2->right = r3;
// Updte the new
heihts for r1, r2, r3
set_height(r1);
set_height(r2);
set_height(r3);
*r = r2;
}
// Doing Left-Right
rotation
void rotate_LR(ROOT
*r) {
NODE *r1=*r,
*r2,*r3,*t1,*t2,*t3,*t4;
r3 = r1->right;
r2 = r3->left;
t2 = r2->left;
t3 = r2->right;
// Actaul rotation
happens here
r1->right = t2;
r3->left = t3;
r2->left = r1;
r2->right = r3;
// Updte the new
heihts for r1, r2, r3
set_height(r1);
set_height(r2);
set_height(r3);
*r = r2;
}
// Doing Right-Right
rotation
void rotate_RR(ROOT
*r) {
NODE
*r1=*r,*r2,*t1,*t2,*t3;
r2 = r1->right;
t1 = r1->left;
t2 = r2->left;
t3 = r2->right;
// Actaul rotation
happens here
r1->right = t2;
r2->left = r1;
set_height(r1);
set_height(r2);
*r = r2;
}
// It will return
rotation type.
int
find_rotation_type(int parent_data, int child_data, int data) {
if(compare(data, parent_data)<0)
{
if(compare(data,
child_data)<0)
return 1;
else if(compare(data,
child_data)==0)
return 0;
else
return 2;
}
else {
if(compare(data,
child_data)>0)
return 4;
else if(compare(data,
child_data)==0)
return 0;
else
return 3;
}}
// Calling the
corresponding AVL-rotation method
void do_rotation(ROOT
*r, int rotation_type) {
if(rotation_type ==
1)
rotate_LL(r);
else if(rotation_type
== 2)
rotate_RL(r);
else if(rotation_type
== 3)
rotate_LR(r);
else if(rotation_type
== 4)
rotate_RR(r);
else
printf("\n\nInvalid
Rotation Type.");
}
int insert(ROOT *r,
int data) {
NODE *new_node, *root
= *r;
int left_h = -1,
right_h = -1;
int
diff,rotation_type;
// Tree is empty
if(root == NULL) {
new_node = (NODE
*)malloc(sizeof(NODE));
new_node->info =
data;
new_node->height =
0;
new_node->left =
new_node->right = NULL;
*r = new_node;
return 0;
}
if(root->left)
left_h =
root->left->height;
if(root->right)
right_h =
root->right->height;
if(compare(data,
root->info)<0) {
left_h =
insert(&(root->left), data);
rotation_type =
find_rotation_type(root->info, root->left->info, data);
}
else if(compare(data,
root->info)>0) {
right_h =
insert(&(root->right), data);
rotation_type =
find_rotation_type(root->info, root->right->info, data);
}
else {
printf("\nYou
Already Used This Number!!\n\n");
return -1;
}
diff =
left_h-right_h;
if(diff>1 ||
diff<-1) {
printf("\nTree
Is Unbalanced At Node Data %d", root->info);
if(rotation_type ==
1)
printf("\nNeed
To Do LL Rotation\n");
if(rotation_type ==
2)
printf("\nNeed
To Do RL Rotation\n");
if(rotation_type ==
3)
printf("\nNeed
To Do LR Rotation\n");
if(rotation_type ==
4)
printf("\nNeed
To Do RR Rotation\n");
// This call is for
doing rotation
do_rotation(r,rotation_type);
printf("\nRotation
Done Successfully. \n\n");
root = *r;
}
// Set the height for
the node and return the height
return
set_height(root);
}
// Printing In-Order
traversal of AVL Tree
void print_inorder(NODE
*root) {
NODE *temp = root;
if(temp) {
print_inorder(temp->left);
printf("%d
",temp->info);
print_inorder(temp->right);
}}
// Printing Pre-Order
traversal of AVL Tree
void
print_preorder(NODE *root) {
NODE *temp = root;
if(temp) {
printf("%d
",temp->info);
print_preorder(temp->left);
print_preorder(temp->right);
}}
// Printing
Post-Order traversal of AVL Tree
void
print_postorder(NODE *root) {
NODE *temp = root;
if(temp) {
print_postorder(temp->left);
print_postorder(temp->right);
printf("%d
",temp->info);
}}
int main() {
ROOT r = NULL;
int
i,num,data,choice;
printf("Enter
How Many Numbers You Want To Insert: ");
scanf("%d",&num);
printf("\nEnter
The Numbers: ");
for(i=0;i<num;i++)
{
scanf("%d",&data);
insert(&r,data);
}
printf("\n\t1.
Insert \t2. In-Order\n\t3. Pre-Order\t4. Post-Order\n\t5. Height Of The Tree
\n\t6. Exit\n");
printf("\nEnter
Your Choice: ");
scanf("%d",&choice);
while(1) {
switch(choice) {
case 1:
printf("\nEnter
The Number: ");
scanf("%d",&data);
insert(&r,data);
break;
case 2:
printf("\nInorder
Traversal: ");
print_inorder(r);
printf("\n");
break;
case 3:
printf("\nPreorder
Traversal: ");
print_preorder(r);
printf("\n");
break;
case 4:
printf("\nPostorder
Traversal: ");
print_postorder(r);
printf("\n");
break;
case 5:
//height of the root
node height is heoght of the tree
printf("\nHeight
Of The Tree: %d\n",r->height);
break;
default:
return 0;
break;
}
printf("\n\t1.
Insert \t2. In-Order\n\t3. Pre-Order\t4. Post-Order\n\t5. Height Of The Tree
\n\t6. Exit\n");
printf("\nEnter
Your Choice: ");
scanf("%d",&choice);
}}