# AVL Tree in C++

In 1962, GM Adelson-Velsky and EM Landis created the AVL Tree. To honor the people who created it, the tree is known as AVL.

The definition of an AVL tree is a height-balanced binary search tree in which each node has a balance factor that is determined by deducting the height of the node's right sub tree from the height of its left sub tree.

If each node's balance factor falls between -1 and 1, the tree is considered to be balanced; otherwise, the tree needs to be balanced.

### Balance Factor

Balance Factor (k) = height (left(k)) - height (right(k))

• The left sub-tree is one level higher than the right sub-tree if the balancing factor of any node is 1.
• Any node with a balance factor of zero indicates that the heights of the left and right sub trees are equal.
• If a node's balancing factor is negative one, the left sub-tree is one level behind the right sub-tree.
• In the following figure, an AVL tree is presented. We can observe that each node's associated balancing factor ranges from -1 to +1. So, it is an illustration of an AVL tree.

### Why use AVL Trees?

The majority of BST operations, including search, max, min, insert, delete, and others, require O(h) time, where h is the BST's height. For a skewed Binary tree, the cost of these operations can increase to O(n). We can provide an upper bound of O(log(n)) for all of these operations if we make sure that the height of the tree stays O(log(n)) after each insertion and deletion. An AVL tree's height is always O(log(n)), where n is the tree's node count.

### Operations on AVL Trees

Due to the fact that, AVL tree is also a binary search tree hence, all the operations are conducted in the same way as they are performed in a binary search tree. Searching and traversing do not lead to the violation in property of AVL tree. However, the actions that potentially break this condition are insertion and deletion; as a result, they need to be reviewed.

• Insertion
• Deletion

### Insertion in AVL Trees

We must add some rebalancing to the typical BST insert procedure to ensure that the provided tree stays AVL after each insertion.

The following two simple operations (keys(left) key(root) keys(right)) can be used to balance a BST without going against the BST property.

• Rotate left
• Rotate right

### The steps to take for insertion are:

• Let w be the newly added node.
• carry out a typical BST insert for w.
• Find the first imbalanced node by moving up starting at w. Assume that z is the initial imbalanced node, y is z's kid who arrives on the path from w to z, and x is z's grandchild that arrives on the aforementioned path.
• Rotate the z-rooted subtree in the proper directions to rebalance the tree. As x, y, and z can be ordered in 4 different ways, there may be 4 potential scenarios that need to be addressed.
• The four potential configurations are as follows:
• Left Left Case: y is z's left child and x's left child.
• Left Right Case: z's right child and x's right child.
• Right Right Case: y is z's right child and x's left child.
• Right Right Case: y is z's right child and x's left child.

The procedures to be carried out in the four circumstances indicated above are listed below. In every instance, we only need to rebalance the subtree rooted with z, and the entire tree will be balanced as soon as the height of the subtree rooted with z equals its pre-insertion value (with the proper rotations).

1. Left Left Case 2. Left Right Case 3. Right Right Case 4. Right Left Case ### Approach for Insertion

The concept is to utilize recursive BST insert, where after insertion, we receive bottom-up pointers to each ancestor individually. Therefore, to go up, we don't require a parent pointer. The recursive code itself ascends and visits every node that was previously inserted.

To put the concept into practice, adhere to the procedures listed below:

• Carry out the standard BST insertion.
• The newly inserted node's ancestor must be the current node. The current node's height should be updated.
• Find the current node's balancing factor (left sub tree height minus right sub tree height).
• The current node is imbalanced and we are either in the Left Left case or Left Right case if the balance factor is larger than 1. Compare the newly inserted key with the key at the left sub tree root to determine if it is left left case or not.

### Program for insertion:

Output:

```Preorder traversal of the constructed AVL tree is
30 20 10 25 40 50
…………………………………………………………………………..
Process executed in 1.22 seconds
Press any key to continue
```

Explanation

Only a few points are updated during the rotation operations (left and right rotate), hence the time required is constant. It also takes a consistent amount of time to update the height and obtain the balancing factor. As a result, the AVL insert has the same temporal complexity as the BST insert, which is O(h), where h is the tree's height. The height is O since the AVL tree is balanced (Logn). Thus, the AVL insert's temporal complexity is O(Logn).

### Comparing it with Red Black Tree

Red Black Tree:

The additional bit that each node possesses in a red-black tree, a type of self-balancing binary search tree, is frequently understood as the color (red or black). The balance of the tree is maintained throughout insertions and deletions thanks to the employment of these colors. Although the tree's balance is not ideal, it is sufficient to cut down on searching time and keep it at or below O(log n), where n is the total number of tree components. The Rudolf Bayer invented this tree in 1972.

All fundamental operations may be completed in O(log n) time by using the AVL tree and other self-balancing search trees like Red Black. Compared to Red-Black Trees, AVL Trees are more evenly distributed, although they may result in more rotations during insertion and deletion. Red Black trees are thus recommended if your application includes frequent, frequent insertions and removals. Additionally, the AVL tree should be chosen over the Red Black Tree if searches are performed more often and insertions and deletions are less frequent.

### Deletion in AVL Trees

We must add some rebalancing to the typical BST delete procedure to ensure that the supplied tree stays AVL after each deletion. The following two simple operations (keys(left) key(root) keys(right)) can be used to rebalance a BST without going against the BST property.

• Left Rotation
• Right Rotation

The tree's T1, T2, and T3 subtrees are rooted with y (on the left side) or x. (on right side) The order of the keys in the two trees mentioned above is as follows:

keys(T1) < key(x) < keys(T2) < key(y) < keys(T3)

Let w represent the removed node:

• Carry out the typical BST delete for w.
• Find the first imbalanced node by moving up starting at w. Let y be the bigger height child of z, x be the larger height child of y, and z be the initial imbalanced node. The definitions of x and y change from insertion here, as you will see.
• Rotate the z-rooted sub tree in the proper directions to rebalance the tree. As x, y, and z can be ordered in 4 different ways, there may be 4 potential scenarios that need to be addressed. The four potential configurations are as follows:
• Left Left Case: y is the left child of z and x is the left child of y
• y is the left child of z and x is the right child of y. (Left Right Case)
• y is z's right-hand kid, and X is y's right-hand child (Right Right Case)
• Z's right kid is y, whereas x is y's left child (Right Left Case)

The procedures to be carried out in the aforementioned 4 circumstances are as follows, just like insertion. Be aware that, unlike insertion, repairing node z won't result in a full fix of the AVL tree.

1. Left Left Case 2. Left Right Case 3. Right Right Case 4. Right Left Case In contrast to insertion, rotation at z may be followed by rotation at z's ancestors in deletion. In order to get to the root, we must thus keep following the path.

### Approach for Deletion

The AVL Tree Deletion C implementation is provided below. The recursive BST delete is the foundation of the following C implementation. After the deletion in the recursive BST delete, we receive bottom-up pointers to each ancestor in turn. Therefore, ascending doesn't require the parent pointer. The recursive code itself ascends and accesses each of the removed node's ancestors.

• Carry out the standard BST delete.
• One of the ancestors of the removed node must be the current node. The current node's height should be updated.
• Find the current node's balancing factor (left sub tree height minus right sub tree height).
• The current node is imbalanced and we are either in Left Left case or Left Right case if the balance factor is larger than 1. Obtain the left sub tree's balancing factor to determine if the situation is Left Left or Left Right. If the left sub tree's balance factor is larger than or equal to 0, it is left left case; otherwise, it is left right case.
• The present node is imbalanced if the balancing factor is less than -1, and we are either in Right Left case or Right Right case. Obtain the balancing factor for the right sub tree to determine if it is the Right Right case or the Right Left case. Right Right case is indicated if the balancing factor of the right sub tree is less than or equal to 0, else Right Left case.

Output:

```Preorder traversal of the constructed AVL tree is
9 1 0 -1 5 2 6 10 11
Preorder traversal after deletion of 10
1 0 -1 9 5 2 6 11
…………………………………………………………………………….
Process executed in 1.11 seconds
Press any key to continue
```

Explanation

The time required is constant since only a small number of points are updated during the rotation operations (left and right rotate). Getting the balance factor and updating the height both take time. As a result, the AVL delete has O(h), where h is the height of the tree, the same temporal complexity as the BST delete. The height is O as a result of the AVL tree's balance (Logn). Thus, the temporal complexity of AVL delete is O. (Log n).

### The benefits of AVL trees:

• The balance of height is constant.
• N is the number of nodes, and height never exceeds logN.
• Compared to a binary search tree, it provides a superior search.
• It has the ability to balance itself.

### Summary

• These binary search trees are self-balancing.
• Balancing Factor values fall between -1 and +1.
• When the balancing factor exceeds the range, rotations must be made.
• Time for insert, delete, and search is O. (log N).
• Avl trees are typically employed in situations where searches occur more frequently than inserts and deletions.

Next TopicDes in C++

### Feedback   