## Learning Outcomes

At the end of this lecture, you’ll be able to:

- Elaborate on the purpose of
**structural rotation**. - Describe, trace and implement structural rotations:
**single right, single left, double right-left, double left-right**. - Explain and trace the balancing operations of an
**AVL tree**. __Select the appropriate rotation type__in order to rebalance an AVL tree after an insertion/removal operation is performed.- Implement the core operations of OrderedMap efficiently with an AVL tree.
- Analyze the time/space efficiency of an AVL tree.

## Lecture Plan

In this lecture, we'll cover the following lessons:

- Structural Rotation: Definition
- Single Rotation: Right
- Right Rotation: Exercise I⚡
- Right Rotation: Exercise II⚡
- Right Rotation: Exercise III⚡
- Right Rotation: Exercise IV⚡
- Single Rotation: Left
- Left Rotation: Exercise⚡
- Double Rotation: Right-Left
- Double Rotation: Left-Right
- Double Rotation: Exercise I⚡
- Double Rotation: Exercise II⚡
- Structural Rotation: Putting it all together!⚡
- Structural Rotation: Exercise⚡
- AVL Tree

Lessons marked with ⚡ contain exercise/activity.

## Downloads

## Structural Rotation: Definition ↗

Consider these numbers: $3, 5, 7$. The following are valid binary search trees made up of the given numbers. However, only one is “balanced”.

It turns out, the four unbalanced trees can be *transformed* to the balanced one using **structural rotation**. (Notice the balanced one can be generated from the sequence $5, 3, 7$ or $5, 7, 3$.)

A structural rotation is an operation on a binary tree that changes the structure of the tree without affecting the order of the elements (as read in by an in-order traversal).

It is used to balance out two branches of different depths.

In a structural rotation, one node is shifted up, another is shifted down, and some of the remaining nodes may be shifted to ensure the tree is still a binary tree (each node only has 2 branches).

Structural rotations change the height of the tree by moving up larger subtrees.

## Single Rotation: Right ↗

Consider inserting the values $7, 5, 3$ in that order.

We start by inserting $7$:

We have a BST with a single node; it is balanced!

Next, we insert $5$.

Now our BST has two nodes. Notice the height and balance factor of the root has changed (and it is still balanced).

Next, we insert $3$.

Our BST has three nodes now. Notice the heights and balance factors of the parent and *grand parent* of $3$ have changed. In particular, the grand parent (the root) is not balanced anymore!

However, if we were to push $7$ to the **right** of $5$, we would restore balance:

This is called a (single) **right rotation**:

Notice the violation of balance property occurred in the grand parent of the newly inserted node. From the perspective of the grand parent node, __the problem was caused in left child’s left subtree.__ The solution is a (single) right rotation to bring the parent node (

*median*value) above the grand parent (

*high*value).

## Right Rotation: Exercise I ↗

Consider the following BST:

Exercise Insert the value $4$ and apply a structural rotation to balance the BST if needed.

## Solution

Let’s observe the original BST is balanced:

Here is the BST after insertion:

Notice the violation of balance property occurs in the grand parent of the newly inserted node. From the perspective of the grand parent node, __the problem is caused in left child’s left subtree.__ This is the pattern which requires (single) right rotation to bring the parent node (

*median*value) above the grand parent (

*high*value).

## Right Rotation: Exercise II ↗

Consider the following BST:

Exercise Remove the value $11$ and apply a structural rotation to balance the BST if needed.

## Solution

Let’s observe the original BST is balanced:

Here is the BST after removal:

Notice the violation of balance property occurs in the parent of the deleted node. From the perspective of the parent node, __the problem is caused in left child’s left subtree.__ This is the pattern which requires a (single) right rotation to bring the left child (

*median*value) above the parent (

*high*value).

## Right Rotation: Exercise III ↗

Consider the following BST:

Exercise Insert the value $3$ and apply a structural rotation to balance the BST if needed.

## Solution

Let’s observe the original BST is balanced:

Here is the BST after insertion:

Notice the violation of balance property occurs in the great grand parent of the inserted node. From the perspective of the great grand parent node, __the problem is caused in left child’s left subtree.__ This is the pattern which requires a (single) right rotation.

**However, this case is a bit tricky:**

When you bring $7$ to be the parent of $14$, the latter needs to go to the right of $7$. However, $11$ is already to the right of $7$. So we need to attach $11$ to the left of $14$ (where $7$ used to be).

## Right Rotation: Exercise IV ↗

Consider the schematic representation of the pattern that leads to a (single) right rotation:

The nodes with dashed line are roots of their own subtree (they could be null too). After the application of right rotation, we get the following:

Exercise Complete the implementation of `rightRotation`

method:

```
Node<T> rightRotation (Node<T> root) {
// TODO Implement me!
}
```

**Note:** The argument to `rightRotation`

is the root of a subtree (not necessarily the root of the BST). The `rightRotation`

must return the updated (new) root. Assume each node has access to its left/right subtrees.

## Solution

```
Node<T> rightRotation (Node<T> root) {
Node<T> child = root.left;
root.left = child.right;
child.right = root;
return child;
}
```

Exercise What is the time complexity of your implementation of `rightRotation`

method?

## Solution

The `rightRotation`

involves a constant number of assignments. Therefore, its time complexity is $O(1)$

## Single Rotation: Left ↗

Consider inserting the values $3, 5, 7$ in that order.

We start by inserting $3$:

We have a BST with a single node; it is balanced!

Next, we insert $5$.

Now our BST has two nodes. Notice the height and balance factor of the root has changed (and it is still balanced).

Next, we insert $7$.

Our BST has three nodes now. Notice the heights and balance factors of the parent and *grand parent* of $7$ have changed. In particular, the grand parent (the root) is not balanced anymore!

However, if we were to push $3$ to the **left** of $5$, we would restore balance:

This is called a (single) **left rotation**:

Notice the violation of balance property occurred in the grand parent of the newly inserted node. From the perspective of the grand parent node, __the problem was caused in right child’s right subtree.__ The solution is a (single) left rotation to bring the parent node (

*median*value) above the grand parent (

*high*value).

## Left Rotation: Exercise ↗

Consider the following BST:

Exercise How many rotations does it take to balance the above BST?

A) 1

B) 2

C) 3

## Solution

Let’s note the heights and balance factors in the original BST:

We can perform a left rotation to bring $4$ to the left of $5$:

We then perform another left rotation to bring $3$ to the left of $5$:

So the answer is **B**, two rotations.

## Double Rotation: Right-Left ↗

Consider inserting the values $3, 7, 5$ in that order.

We start by inserting $3$:

We have a BST with a single node; it is balanced!

Next, we insert $7$.

Now our BST has two nodes. Notice the height and balance factor of the root has changed (and it is still balanced).

Next, we insert $5$.

Our BST has three nodes now. Notice the heights and balance factors of the parent and *grand parent* of $5$ have changed. In particular, the grand parent (the root) is not balanced anymore!

No single rotation will fix the imbalance!

However, if we were to push $7$ to the **right** of $5$, we would *transform* the structure to a pattern we have seen before:

## The above arrangement is a (single) left rotation away from balance

So we perform a **left** rotation:

As you have noticed, we needed two rotations, first a right and then a left rotation. This is called a (double) **right-left rotation**.

Notice the violation of balance property occurred in the grand parent of the newly inserted node. From the perspective of the grand parent node, __the problem was caused in right child’s left subtree.__ The solution is a (double) left-right rotation to bring the

*median*value above the high and low values.

## Double Rotation: Left-Right ↗

Consider inserting the values $7, 5, 3$ in that order.

We start by inserting $7$:

We have a BST with a single node; it is balanced!

Next, we insert $3$.

Next, we insert $5$.

Our BST has three nodes now. Notice the heights and balance factors of the parent and *grand parent* of $5$ have changed. In particular, the grand parent (the root) is not balanced anymore!

No single rotation will fix the imbalance!

However, if we were to push $3$ to the **left** of $5$, we would *transform* the structure to a pattern we have seen before:

## The above arrangement is a (single) right rotation away from balance

So we perform a **right** rotation:

As you have noticed, we needed two rotations, first a left and then a right rotation. This is called a (double) **left-right rotation**.

Notice the violation of balance property occurred in the grand parent of the newly inserted node. From the perspective of the grand parent node, __the problem was caused in left child’s right subtree.__ The solution is a (double) right-left rotation to bring the

*median*value above the high and low values.

## Double Rotation: Exercise I ↗

Consider the following BST:

Exercise Insert the value $23$ and apply a structural rotation to balance the BST if needed.

## Solution

Let’s observe the original BST is balanced:

Here is the BST after insertion:

Notice the violation of balance property occurs in the great grand parent of the newly inserted node. From the perspective of the grand parent node, __the problem is caused in right child’s left subtree (the highlighted nodes).__ This is the pattern which requires (double) right-left rotation to rebalance.

So we perform a right rotation to bring $22$ above $25$ (to bring the median value on a level between the low and high values):

And then a left rotation to bring $22$ above $20$ (to bring the median value on a level above the low and high values):

## Double Rotation: Exercise II ↗

Consider the following BST:

Exercise Remove the value $13$ and apply a structural rotation to balance the BST if needed.

## Solution

Let’s observe the original BST is balanced:

Here is the BST after removal:

Notice the violation of balance property occurs in the parent of node which was removed. From the perspective of the parent node, __the problem is caused in left child’s right subtree. (the highlighted nodes)__ This is the pattern which requires (double) left-right rotation to rebalance.

So we perform a left rotation to bring $10$ above $9$ (to bring the median value on a level between the low and high values):

And then a right rotation to bring $10$ above $12$ (to bring the median value on a level above the low and high values):

## Structural Rotation: Putting it all together! ↗

This is called a (single) **right rotation**:

Cause of imbalance: **left child’s left subtree**.

This is called a (single) **left rotation**:

Cause of imbalance: **right child’s right subtree**.

This is called a (double) **right-left rotation**:

Cause of imbalance: **right child’s left subtree**.

This is called a (double) **left-right rotation**:

Cause of imbalance: **left child’s right subtree**.

Exercise Complete the following table which assists in determining type of rotation.

Imbalance Node | Child’s `bf = -1` (right heavy) | Child’s `bf = 1` (left heavy) |
---|---|---|

`bf = -2` (right heavy) | ||

`bf = 2` (left heavy) |

## Solution

Imbalance Node | Child’s `bf = -1` (right heavy) | Child’s `bf = 1` (left heavy) |
---|---|---|

`bf = -2` (right heavy) | Left | Right-Left |

`bf = 2` (left heavy) | Left-Right | Right |

**Caution** The table above does not account for an edge case where the child’s balance factor is $0$.

## Schematic representation of tree rotations

## Resources

- Wikipedia’s entry on AVL Tree: Rebalancing
- Wikipedia’s entry on Tree Rotation.

## Structural Rotation: Exercise ↗

Exercise Starting from an empty BST, perform the following operations in order. Apply structural rotations, if needed, to keep the BST balanced.

```
insert(15)
insert(20)
insert(24)
insert(10)
insert(13)
insert(7)
insert(30)
insert(36)
insert(25)
remove(24)
remove(20)
```

## Solution

Visit this interactive visualizer and carry the operations.

The final BST should look like this:

## AVL Tree ↗

AVL Tree, named after its inventors Adelson-Velskii and Landis, is a **self-balancing** binary search tree that maintains the height balance property (in addition to the BST order property) using structural rotations.

The insertion and deletion operations for AVL trees begin similarly to the corresponding operations for (regular) binary search trees. It then performs *post-processing* structural rotations to restore the balance of any portions of the tree that are adversely affected by the insertion/removal.

**Insertion**

- Insert item as in binary search tree.
- Starting with new node, go up to update heights.
- If find a node that has become unbalanced, do rotation to rebalance.
- Rebalance reduces height of sub-tree by $1$, so no need to propagate up – only one adjustment needed at most because it was previously balanced before the insert.
- So, in total, $O(\lg N)$ to insert and $O(1)$ to rebalance.

**Removal**

- Remove item as in binary search tree.
- Starting with the parent of the deleted node, go up to update heights.
- By “deleted node,” I mean the
*actual*deleted node (which is going to be a leaf) not the node which its value was replaced with in-order predecessor/successor. - As you go up from the deleted node to update the heights of its ancestors, rebalance them as needed (perform rotation).
- Rotations may reduce the height of a subtree, causing further imbalances for ancestors, so you may need to perform more than one rebalancing operation.
- Since you travel from the deleted node upwards to the root, at most you will perform $O(\lg n)$ rotations.
- So, in total, $O(\lg n)$ to remove and $O(\lg n)$ to rebalance.

**Recommendation**: Implement insertion/removal (with structural rotations) __recursively__!

For the implementation of AVL Tree, you must store the height of each node.

As you insert/remove, you must travel upward towards the root to update the height of ancestors.

## Resources

- Wikipedia’s entry on AVL Tree
- VisualAlgo interactive demo for BST and AVL Tree