Final Project
Final Project
Implementation of AVL
Document Prepared By
Zeeshan Ahmad S2019027005
Ali Raza S2019027015
Fawad Afzal S2019027032
AVL TREE PROJECT
1. Definition
AVL tree is a self-balancing Binary Search Tree. The difference between heights of left subtree
and right subtree cannot be more than one for all nodes.
Most of the Binary Search Tree operations take O (h) time where h is the height of the BST. The
cost of these operations may become O (n) for a skewed Binary tree. In a skewed binary tree,
all nodes except one have only one child node. The remaining node has no child. If we make
sure that height of the tree remains O (Log n) after every insertion and deletion, then we can
guarantee an upper bound of O (Log n) for all these operations. The height of an AVL tree is
always O (Log n) where n is the number of nodes in the tree.
A Binary tree is defined to be an AVL if the balance factor = {-1 0 1} of each node
holds this value. A node with 1 balance factor is call Left Heavy and a node with -1 balance
factor is called Right Heavy, and a node with 0 balance factor is called balanced.
2. Operation
2.1. Insertion
When inserting a node into an AVL tree, you initially follow the same process as
inserting into a Binary Search Tree. If the tree is empty, then the node is inserted as
the root of the tree. In case the tree has not been empty then we go down the root,
and recursively go down the tree searching for the location to insert the new node.
This traversal is guided by the comparison function. In this case, the node always
replaces a NULL reference (left or right) of an external node in the tree i.e., the node
is either made a left-child or a right-child of the external node.
To make sure that the given tree remains AVL after every insertion, we must
augment the standard BST insert operation to perform some re-balancing.
Left rotation
If a tree becomes unbalanced, when a node is inserted into the right subtree of
the right subtree, then we perform a single left rotation
Node A has become unbalanced as a node is inserted in the right subtree of A's
right subtree. We perform the left rotation by making A the left-subtree of B.
Right rotation
AVL tree may become unbalanced, if a node is inserted in the left subtree of the
left subtree. The tree then needs a right rotation.
Left-Right rotation
A node has been inserted into the right subtree of the left subtree. This
makes C an unbalanced node. These scenarios cause AVL tree to perform
left-right rotation. We first perform the left rotation on the left subtree of C.
This makes A, the left subtree of B. Node C is still unbalanced, however
now, it is because of the left-subtree of the left-subtree.
We shall now right-rotate the tree, making B the new root node of
this subtree. C now becomes the right subtree of its own left subtree.
Now the tree is balanced.
Right-Left rotation
The second type of double rotation is Right-Left Rotation. It is a combination of
right rotation followed by left rotation.
A node has been inserted into the left subtree of the right subtree. This makes A, an
unbalanced node with balance factor 2. First, we perform the right rotation
along C node, making C the right subtree of its own left subtree B. Now, B becomes
the right subtree of A. Node A is still unbalanced because of the right subtree of its
right subtree and requires a left rotation.
A left rotation is performed by making B the new root node of the
subtree. A becomes the left subtree of its right subtree B. The tree is now balanced
Algorithm:
Code in C++:
Insert 24,2,32
0
24
0 0
2 32
-1 -2
2 32
1
0
7 42
Left Rotation
0
37
-1
24
-1 -2
2 32
1 Left Rotation
0
7 37
0
42
0
24
-1 0
2 37
0 0
0
7 32 42
-1
24
-2 -1
Left Rotation
2 37
-1 0 1
7 32 42
0 0
20 40
-1
24
0 -1
Left Rotation
7 37
0 0
0 1
2 20 32 42
0
40
Insert 42, 5
-1
24
0 -1
Left Rotation
7 37
0 0
0 1
2 20 32 42
0 0
5 40 42
2.3. Searching
Finding a specific node in an AVL tree can be done the same way as that of balanced or
unbalanced BST.
Algorithm:
The procedure begins its search at the root and traces a simple path downward in the tree. For
each node it encounters, it compares the key k with node. If the two are equal, the search
terminates. If key is smaller than the search continues in the left subtree of node, if key is larger
than the search continues in the right subtree. The nodes encountered during the recursion form
a simple path downward from the root of the tree, and thus the running time of Find is O.(h),
where h is the height of the tree.
Code in C++:
Print ( tree, q )
{
Print (tree.right, q+1)
If (tree == r) // R is the length of the tree
Print root.
For (i = 0 , I < l and tree != r)
{
Print tree
Print (tree.left ,q+1)
}
}
if (p != NULL) {
print(p->right, l + 1);
cout << " ";
if (p == r)
cout << "Root -> ";
for (int i = 0; i < l&& p != r; i++)
cout << " ";
cout << p->data;
print(p->left, l + 1);
}
}
Unlike linear data structures which have only one logical way to traverse them, trees
can be traversed in different ways. Following are the generally used ways for
traversing trees.