×

AVL Tree

AVL Tree

AVL Tree is referred to as self-balanced or height-balanced binary search tree where the difference between heights of its left subtree and right subtree (Balance Factor) can't more than one for all nodes covered by a tree.

Example:

We can say a tree is balanced if the balance factor of each node of a tree is in between -1 to 1; otherwise, a tree is considered as unbalanced and need to balance.

                        Balance Factor (node) = height (left (node)) – height (right (node))

  • If the balance factor is 1 of any node of the tree, then we can say the height of the left subtree is higher than the height of the right subtree of the node in the AVL tree.
  • If the balance factor is 0 of any node of the tree, then we can say the height of the left subtree is equal to the height of the right subtree of the node in the AVL tree.
  • If the balance factor is -1 of any node of the tree, then we can say the height of the left subtree is lower than the height of the right subtree of the node in the AVL tree.

Need for AVL Trees

If we talk about operations of binary search tree take O (log n) time. The time complexity of these operations could be O(n) if the binary search tree skewed (if the input to the binary search tree comes in an ascending or descending manner) and if we make sure the height of the binary search tree is balanced so we can guarantee that all these operations will take O(log n) time.

AVL Tree Operations

As we discussed, the AVL tree is a special type of binary search tree, so the operations of the AVL tree are the same as the binary search tree without violation of AVL property.

  • Insertion: -

In this, we add a new node to the AVL tree. Sometimes it may lead to violating the property of AVL, so we need to re-balance the tree by applying the rotation on it.

  • Deletion: -

In this, we delete a node from the AVL tree. It may disturb the balance of the AVL tree, so the tree needs to be re-balanced.

Rotations of AVL Tree:

There are four types of rotations of AVL, which are given below:

  • Right Rotation on AVL Tree: -

When the AVL tree is unbalanced because a node is inserted into the left subtree of the Z in the AVL tree, then we have to perform the right rotation on AVL; it is a clockwise rotation.

  • Left Rotation on AVL Tree: -

When the AVL tree is unbalanced because a node is inserted into the right subtree of Z in the AVL tree, then we have to perform left rotation on AVL; it is an anti-clockwise rotation.

  • Left - Right Rotation on AVL Tree

Doubled rotation is a bit difficult version of AVL rotation. In Left - Right rotation, we perform the left rotation first, then the right rotation after it.

A node has been added into the right subtree of the left subtree. Because of this, Z becomes an unbalanced node. So, we need to perform left-right rotation on this type of problem in the AVL tree.      
Firstly, we need to perform the left rotation on the left subtree of Z. This makes X the left subtree of Y.
Node z is not balanced yet; it is because of the left-sub tree of the left-sub tree in the AVL tree, or its balance factor is still 2.
We have to make Y the new root node of the tree by doing the right rotation on Z. Now, Z becomes the right subtree of Y.
The tree is now balanced.
  • Right - Left Rotation on AVL Tree: -

It is another type of double rotation version. In the right – Left rotation, we perform the right rotation first, then the left rotation after it.

A node has been added into the left subtree of the right subtree. Because of this, X becomes an unbalanced node with balance factor -2, so we have to balance the AVL tree by performing right-left rotation on it.
First of all, we perform the right rotation on the Z node, making Z the right subtree of the Y subtree. Now, Y becomes the right subtree of X in the AVL tree.
Node X is not balanced yet, because of the right subtree of its right subtree in the AVL tree or its balance factor is still -2.
We have to make Y the new root node of the tree by doing a left rotation on X. Now X becomes the left subtree of Y.
Now, the tree is balanced.

Implementation of AVL Tree in C Language: -

#include<stdio.h> 

typedef struct node

{

          int data;

          struct node *left, *right;

          int ht;

}node;

node *insert(node *, int);

node *Delete(node *, int);

void preorder(node *);

void inorder(node *);

int height( node *);

node *rotate_right(node *);

node *rotate_left(node *);

node *right_rotation(node *);

node *left_rotation(node *);

node *left_right_rotation(node *);

node *right_left_rotation(node *);

int balance_factor(node *);

int main()

{

          node *root = NULL;

          int x, n, i, op;

          do

          {

                   printf("\n1)Create: ");

                   printf("\n2)Insert: ");

                   printf("\n3)Delete: ");

                   printf("\n4)Print: ");

                   printf("\n5)Quit: ");

                   printf("\n\nEnter Your Choice: ");

                   scanf("%d", &op);                 

                   switch (op)

                   {

                             case 1: printf("\nEnter no. of elements: ");

                                                scanf("%d", &n);

                                                printf("\nEnter tree data: ");

                                                root = NULL;

                                                for(i = 0; i<n; i++)

                                                {

                                                          scanf("%d", &x);

                                                          root = insert(root, x);

                                                }

                                                break;

                             case 2: printf("\nEnter a data: ");

                                                scanf("%d", &x);

                                                root = insert(root, x);

                                                break;

                             case 3: printf("\nEnter a data: ");

                                                scanf("%d", &x);

                                                root = Delete(root, x);

                                                break;

                             case 4: printf("\nPreorder sequence: \n");

                                                preorder( root );

                                                printf("\n\nInorder sequence: \n");

                                                inorder( root );

                                                printf("\n");

                                                break;                           

                   }

          }while(op != 5);   

          return 0;

}

node * insert(node *temp, int x)

{

          if(temp == NULL)

          {

                   temp = (node*) malloc (sizeof(node));

                   temp->data = x;

                   temp->left = NULL;

                   temp->right = NULL;

          }

          else

                   if(x > temp-> data)                 // insert in right sub tree

                   {

                             temp->right = insert(temp->right, x);

                             if(balance_factor(temp) == -2)

                                      if(x>temp->right->data)

                                                temp = right_rotation(temp);

                                      else

                                                temp = right_left_rotation(temp);

                   }

                   else

                             if(x < temp->data)

                             {

                                      temp->left = insert(temp->left, x);

                                      if(balance_factor(temp) == 2)

                                                if(x < temp->left->data)

                                                          temp = left_rotation(temp);

                                                else

                                                          temp = left_right_rotation(temp);

                             }

                   temp->ht = height(temp);

                   return(temp);

}

node * Delete(node *temp, int x)

{

          node *p;

          if(temp == NULL)

          {

                   return NULL;

          }

          else

                   if(x > temp->data)                  // insert in right sub tree

                   {

                             temp->right = Delete(temp->right, x);

                             if(balance_factor(temp) == 2)

                                      if(balance_factor(temp->left) >= 0)

                                                temp = left_rotation(temp);

                                      else

                                                temp = left_right_rotation(temp);                                    

                   }

                   else

                             if(x < temp->data)

                             {

                                      temp->left = Delete(temp->left,x);

                                      if(balance_factor(temp) == -2)        //Rebalance tree

                                                if(balance_factor(temp->right)<=0)

                                                          temp = right_rotation(temp);

                                                else

                                                          temp = right_left_rotation(temp);

                             }

                             else

                             {

                                      // data to be deleted is found

                                      if(temp->right != NULL)

                                      {        //delete its inorder succesor

                                                p = temp->right;

                                                while(p->left != NULL)

                                                          p = p->left;

                                                temp->data = p->data;

                                                temp->right = Delete(temp->right, p->data);

                                                if(balance_factor(temp) == 2) //Rebalance tree

                                                          if(balance_factor(temp->left) >= 0)

                                                                   temp = left_rotation(temp);

                                                          else

                                                                   temp = left_right_rotation(temp);

                                      }

                                      else

                                                return(temp->left);

                             }

          temp->ht = height(temp);

          return(temp);

}

int height(node * temp)

{

          int lh,rh;

          if(temp == NULL)

                   return(0);

          if(temp->left == NULL)

                   lh = 0;

          else

                   lh = 1+ temp->left->ht;

          if(temp->right == NULL)

                   rh = 0;

          else

                   rh = 1+ temp->right->ht;

          if(lh > rh)

                   return(lh);

          return(rh);

}

node * rotate_right(node *x)

{

          node *y;

          y = x->left;

          x->left = y->right;

          y->right = x;

          x->ht = height(x);

          y->ht = height(y);

          return(y);

}

node * rotate_left(node *x)

{

          node *y;

          y = x->right;

          x->right = y->left;

          y->left = x;

          x->ht = height(x);

          y->ht = height(y);

          return(y);

}

node * right_rotation(node *temp)

{

          temp = rotate_left(temp);

          return(temp);

}

node * left_rotation(node *temp)

{

          temp = rotate_right(temp);

          return(temp);

}

node * left_right_rotation(node *temp)

{

          temp->left = rotate_left(temp->left);

          temp = rotate_right(temp);

          return(temp);

}

node * right_left_rotation(node *temp)

{

          temp->right = rotate_right(temp->right);

          temp = rotate_left(temp);

          return(temp);

}

int balance_factor(node *temp)

{

          int lh,rh;

          if(temp == NULL)

                   return(0);

          if(temp->left == NULL)

                   lh = 0;

          else

                   lh = 1+temp->left->ht;

          if(temp->right == NULL)

                   rh = 0;

          else

                   rh = 1+temp->right->ht;

          return(lh - rh);

}

void preorder(node *temp)

{

          if(temp != NULL)

          {

                   printf("%d(Bf = %d)", temp->data,balance_factor(temp));

                   preorder(temp->left);

                   preorder(temp->right);

          }

}

void inorder(node *temp)

{

          if(temp != NULL)

          {

                   inorder(temp->left);

                   printf("%d(Bf = %d)",temp->data, balance_factor(temp));

                   inorder(temp->right);

          }

}

Output: -

Time Complexity of AVL Tree

The rotations of the AVL tree take constant time. It is a self-balanced tree, so the time complexity of all the operations (e.g., insertion, deletion and searching) is O (log n).

Applications of AVL Tree

  • It is used for indexing large records in the database.
  • Also, it is used for efficient searching or finding the record from the database efficiently.

Related Topics

Create a binary search tree

Implementation In this section of the article, we will see the usage and mechanism of how we will create a given binary tree. Let's observe these in more depth and then...

7 minutes read.

Linear vs Circular Queue: Data Structure

Difference Between Linear and Circular Queue What is Linear Queue? A linear queue is linear data structure which works on first in first out principle. We can say a linear queue is...

3 minutes read.

Priority Queue in Data Structure

Priority Queue A priority queue is a special kind of queue, in priority queue we give some priority to an element and according to this priority an element can be served...

3 minutes read.

Shell Sort

Shell Sort: Shell sort is a sorting algorithm. It is an extended version of the insertion sort. In this sorting, we compare the elements that are distant apart rather than the...

5 minutes read.

Deletion Operation of the binary search tree in C++ language

A typical binary search tree implements some order to carry out the arrangements. As the name suggests, each parent node should have at most two children. The main rule in...

4 minutes read.

What are Forest Trees in Data Structure

Data structure A data model manages and optimizes computer resources, and a database stores and manages data. It's one of many uses for data structures to hold data. Data structures come...

5 minutes read.

CSS Text-indent

Text-indent The Text-indent property of CSS is used to set any first line’s indentation inside a text’s block. It describes the horizontal space amount that puts establish before the text line. It...

3 minutes read.

What Should We Learn First? Trees or Graphs in Data Structures

A data structure is a database used to store and manage data and optimize and manage computing resources. A data structure is a form used intelligently and quickly to store,...

6 minutes read.

What is B tree?

What do you mean by B Tree in Data Structures? In the technological world, a B tree is simply a well-managed and coordinated tree and an integral part of the data...

6 minutes read.

Tree vs Graph: Data Structure

Difference Between Tree and Graph What is Tree? A tree is a non-linear data structure and finite collection of elements called node. A tree, in which the data items are arranged in...

3 minutes read.

Dijkstra’s vs Bellman-Ford Algorithm

The Dijkstra Algorithm One of the SSSP (Single Source Shortest Path) algorithms is Dijkstra's. As a result, it finds the shortest path between a source node and all other nodes in...

7 minutes read.

Cycle sort

Cycle sort is an examination arranging calculation which powers exhibit to be figured into the quantity of cycles where every one of them can be pivoted to create an arranged...

5 minutes read.

Partitioning a linked list around a given value

Partitioning a linked list around a given value In this problem, we are given a linked list and a value k. We need to partition the given linked list so that...

3 minutes read.

Find the nth node from the end of a Linked List

Find the nth node from the end of a Linked List In this problem, we have given a singly linked list and a number 'n,' and we need to find the...

3 minutes read.

Extended Binary Tree

An extended binary tree is a binary tree in which all the NILL subtrees present mainly in the original trees are exchanged with the special nodes that are primarily known...

3 minutes read.

Does Overloading Work with Inheritance

This is a question that occasionally comes to many programmers. Who are curious to know more now has a complete explanation and a solution through this tutorial! Inheritance: The functions of...

3 minutes read.

Binary Tree vs Binary Search Tree: Data Structure

Difference Between Binary Tree and Binary Search Tree What is Binary Tree? A tree which each node can have utmost two children called binary tree. These children are referred as the ‘left...

3 minutes read.

Heap Sort vs Merge Sort

In this article, we are going to discuss the Heap Sort, Merge sort and the difference between them. What is Heap Sort? Heap – A heap is an abstract data type categorised...

7 minutes read.

Bin Packing Problem (How to minimize the number of used Bins)

You have been given an array. The values of the array represent the size of n different items. You have been also given some bins. You have to store the...

3 minutes read.

Deque in Data Structure

Deque A deque referred as “Double-Ended Queue”, is a linear collection of data items same like queue data structure. deque has two ends, front end and rear end, deque is the...

27 minutes read.