35 - Data Structure and Algorithms - AVL Trees
35 - Data Structure and Algorithms - AVL Trees
35 - Data Structure and Algorithms - AVL Trees
AVL Trees
In AVL trees, the difference between the heights of left and right subtrees,
known as the Balance Factor, must be at most one. Once the difference
exceeds one, the tree automatically executes the balancing algorithm until the
difference becomes one again.
There are usually four cases of rotation in the balancing algorithm of AVL
trees: LL, RR, LR, RL.
LL Rotations
LL rotation is performed when the node is inserted into the right subtree
leading to an unbalanced tree. This is a single left rotation to make the tree
balanced again −
Fig : LL Rotation
The node where the unbalance occurs becomes the left child and the newly
added node becomes the right child with the middle node as the parent node.
RR Rotations
RR rotation is performed when the node is inserted into the left subtree
leading to an unbalanced tree. This is a single right rotation to make the tree
balanced again −
Fig : RR Rotation
The node where the unbalance occurs becomes the right child and the newly
added node becomes the left child with the middle node as the parent node.
LR Rotations
LR rotation is the extended version of the previous single rotations, also called
a double rotation. It is performed when a node is inserted into the right subtree
of the left subtree. The LR rotation is a combination of the left rotation
followed by the right rotation. There are multiple steps to be followed to carry
this out.
Consider an example with “A” as the root node, “B” as the left child of
“A” and “C” as the right child of “B”.
After the rotation, the C node becomes the left child of A and B becomes
the left child of C.
The unbalance still persists, therefore a right rotation is applied at the
root node A and the left child C.
After the final right rotation, C becomes the root node, A becomes the
right child and B is the left child.
Fig : LR Rotation
RL Rotations
Consider an example with “A” as the root node, “B” as the right child of
“A” and “C” as the left child of “B”.
After the rotation, the C node becomes the right child of A and B
becomes the right child of C.
The unbalance still persists, therefore a left rotation is applied at the
root node A and the right child C.
After the final left rotation, C becomes the root node, A becomes the left
child and B is the right child.
Fig : RL Rotation
The basic operations performed on the AVL Tree structures include all the
operations performed on a binary search tree, since the AVL Tree at its core is
actually just a binary search tree holding all its properties. Therefore, basic
operations performed on an AVL Tree are − Insertion and Deletion.
Insertion
The data is inserted into the AVL Tree by following the Binary Search Tree
property of insertion, i.e. the left subtree must contain elements less than the
root value and right subtree must contain all the greater elements. However, in
AVL Trees, after the insertion of each element, the balance factor of the tree is
checked; if it does not exceed 1, the tree is left as it is. But if the balance factor
exceeds 1, a balancing algorithm is applied to readjust the tree such that
balance factor becomes less than or equal to 1 again.
Algorithm
The following steps are involved in performing the insertion operation of an
AVL Tree −
Step 3 − If the tree is empty, the new node created will become the root node of
the AVL Tree.
Step 4 − If the tree is not empty, we perform the Binary Search Tree insertion
operation and check the balancing factor of the node in the tree.
Step 5 − Suppose the balancing factor exceeds ±1, we apply suitable rotations
on the said node and resume the insertion from Step 4.
START
else
return node
rightRotate
leftRotate
rightRotate
leftRotate (node)
return node
END
Insertion Example
Starting with the first element 1, we create a node and measure the balance,
i.e., 0.
Since both the binary search property and the balance factor are satisfied, we
insert another element into the tree.
The balance factor for the two nodes are calculated and is found to be -1
(Height of left subtree is 0 and height of the right subtree is 1). Since it does
not exceed 1, we add another element to the tree.
Now, after adding the third element, the balance factor exceeds 1 and becomes
2. Therefore, rotations are applied. In this case, the RR rotation is applied
since the imbalance occurs at two right nodes.
Example
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
int height;
};
if (N == NULL)
return 0;
return N->height;
return (a > b) ? a : b;
node->data = data;
node->leftChild = NULL;
node->rightChild = NULL;
node->height = 1;
return (node);
x->rightChild = y;
y->leftChild = T2;
return x;
y->leftChild = x;
x->rightChild = T2;
x->height = max(height(x->leftChild), height(x->rightChild)) + 1;
return y;
if (N == NULL)
return 0;
if (node == NULL)
return (newNode(data));
else
return node;
node->height = 1 + max(height(node->leftChild),
height(node->rightChild));
return rightRotate(node);
return leftRotate(node);
node->leftChild = leftRotate(node->leftChild);
return rightRotate(node);
node->rightChild = rightRotate(node->rightChild);
return leftRotate(node);
return node;
return current;
if (root == NULL)
return;
if (root != NULL) {
printTree(root->leftChild);
printTree(root->rightChild);
int main(){
printTree(root);
return 0;
Output
AVL Tree: 14 22 25 44 63 72 98
Deletion
START
if root == null: return root
else:
if (temp == root.left)
temp = root.right
else
temp = root.left
temp = root
root = null
else
root = temp
else:
return root
balance = getBalance
rightRotate
rightRotate
leftRotate
leftRotate
return root
END
Deletion Example
Using the same tree given above, let us perform deletion in three scenarios −
However, element 6 is not a leaf node and has one child node attached to it. In
this case, we replace node 6 with its child node: node 5.
The balance of the tree becomes 1, and since it does not exceed 1 the tree is
left as it is. If we delete the element 5 further, we would have to apply the left
rotations; either LL or LR since the imbalance occurs at both 1-2-4 and 3-2-4.
The balance factor is disturbed after deleting the element 5, therefore we apply
LL rotation (we can also apply the LR rotation here).
Once the LL rotation is applied on path 1-2-4, the node 3 remains as it was
supposed to be the right child of node 2 (which is now occupied by node 4).
Hence, the node is added to the right subtree of the node 2 and as the left child
of the node 4.
The balance of the tree still remains 1, therefore we leave the tree as it is
without performing any rotations.
Example
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
};
if (N == NULL)
return 0;
return N->height;
return (a > b) ? a : b;
node->data = data;
node->leftChild = NULL;
node->rightChild = NULL;
node->height = 1;
return (node);
}
struct Node *rightRotate(struct Node *y){
x->rightChild = y;
y->leftChild = T2;
return x;
y->leftChild = x;
x->rightChild = T2;
return y;
return 0;
if (node == NULL)
return (newNode(data));
else
return node;
node->height = 1 + max(height(node->leftChild),
height(node->rightChild));
return rightRotate(node);
node->leftChild = leftRotate(node->leftChild);
return rightRotate(node);
node->rightChild = rightRotate(node->rightChild);
return leftRotate(node);
return node;
current = current->leftChild;
return current;
if (root == NULL)
return root;
else {
if (temp == NULL) {
temp = root;
root = NULL;
} else
*root = *temp;
free(temp);
} else {
root->data = temp->data;
}
}
if (root == NULL)
return root;
root->height = 1 + max(height(root->leftChild),
height(root->rightChild));
return rightRotate(root);
root->leftChild = leftRotate(root->leftChild);
return rightRotate(root);
return leftRotate(root);
root->rightChild = rightRotate(root->rightChild);
return leftRotate(root);
return root;
}
if (root != NULL) {
printTree(root->leftChild);
printTree(root->rightChild);
int main(){
printTree(root);
printTree(root);
return 0;
Output
AVL Tree: 14 22 25 44 63 72 98
After deletion: 14 22 44 63 72 98
Example
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
int height;
};
if (N == NULL)
return 0;
return N->height;
return (a > b) ? a : b;
node->data = data;
node->leftChild = NULL;
node->rightChild = NULL;
node->height = 1;
return (node);
x->rightChild = y;
y->leftChild = T2;
return x;
y->leftChild = x;
x->rightChild = T2;
if (N == NULL)
return 0;
if (node == NULL)
return (newNode(data));
else
return node;
node->height = 1 + max(height(node->leftChild),
height(node->rightChild));
return rightRotate(node);
return leftRotate(node);
node->leftChild = leftRotate(node->leftChild);
return rightRotate(node);
node->rightChild = rightRotate(node->rightChild);
return leftRotate(node);
return node;
current = current->leftChild;
return current;
}
if (root == NULL)
return root;
else {
if (temp == NULL) {
temp = root;
root = NULL;
} else
*root = *temp;
free(temp);
} else {
if (root == NULL)
return root;
root->height = 1 + max(height(root->leftChild),
height(root->rightChild));
return rightRotate(root);
root->leftChild = leftRotate(root->leftChild);
return rightRotate(root);
return leftRotate(root);
root->rightChild = rightRotate(root->rightChild);
return leftRotate(root);
return root;
if (root != NULL) {
printTree(root->leftChild);
printTree(root->rightChild);
int main(){
printTree(root);
printTree(root);
return 0;
Output
AVL Tree: 14 22 25 44 63 72 98
After deletion: 14 22 44 63 72 98