Chapter 28: DSA AVL Trees
DSA AVL Trees – Let’s learn this topic properly and in depth, like I’m sitting next to you with a whiteboard, drawing trees step by step, explaining every concept slowly and clearly, showing rotations with detailed examples, and most importantly telling you why AVL trees exist, when they are useful, and how they differ from ordinary BSTs.
What is an AVL Tree?
An AVL Tree is a self-balancing Binary Search Tree (BST) where the height difference (called balance factor) between the left and right subtrees of every node is at most 1.
It was the first self-balancing BST ever invented (by Adelson-Velsky and Landis in 1962 — hence AVL).
The key property:
Balance factor of a node = height(left subtree) − height(right subtree)
And this balance factor must always be −1, 0, or +1 for every node in the tree.
If after any insertion or deletion the balance factor of any node becomes +2 or −2, we immediately perform rotations to restore the balance.
Why do we need AVL Trees? (very important motivation)
Normal Binary Search Tree problems:
- If you insert elements in sorted order (or almost sorted) → tree becomes skewed (like a linked list)
Example:
Insert 10, 20, 30, 40, 50, 60 → tree becomes:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
10 \ 20 \ 30 \ 40 \ 50 \ 60 |
- Height = O(n) instead of O(log n)
- Search / insert / delete → O(n) worst case (same as linked list)
AVL tree fixes this by automatically rebalancing itself after every insert/delete operation so that:
- Height is always kept O(log n)
- All operations remain O(log n) in worst case (not just average)
Balance Factor & Height
Height of a node = longest path from that node to a leaf (leaf height = 0)
Balance Factor = height(left) − height(right)
Allowed values: −1, 0, +1
Examples:
|
0 1 2 3 4 5 6 7 8 |
10 balance = 0 / \ 5 15 both sides height 0 |
|
0 1 2 3 4 5 6 7 8 |
10 balance = +1 / 5 left height 0, right height -1 (no right child) |
|
0 1 2 3 4 5 6 7 8 |
10 balance = -1 \ 15 left height -1 (no left), right height 0 |
|
0 1 2 3 4 5 6 7 8 9 10 |
10 balance = +2 ← violation! / 5 / 3 |
→ This tree is unbalanced → we must rotate
The Four Possible Imbalance Cases & Rotations
When balance factor becomes +2 or −2, we fix it using rotations.
There are four cases:
- Left-Left (LL) violation → balance = +2 and left child balance ≥ 0 → Right Rotation (single rotation)
- Left-Right (LR) violation → balance = +2 and left child balance = −1 → Left-Right Rotation (double rotation)
- Right-Right (RR) violation → balance = −2 and right child balance ≤ 0 → Left Rotation (single rotation)
- Right-Left (RL) violation → balance = −2 and right child balance = +1 → Right-Left Rotation (double rotation)
Most Important: Right Rotation (LL case) – Visual & Code
Before (balance factor +2 at node 10):
|
0 1 2 3 4 5 6 7 8 9 10 |
10 balance +2 / 5 / 3 |
After Right Rotation:
|
0 1 2 3 4 5 6 7 8 |
5 / \ 3 10 |
Right Rotation code (on node y):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
def rightRotate(y): x = y.left T2 = x.right # Perform rotation x.right = y y.left = T2 # Update heights (we'll add height later) return x |
Left Rotation (RR case)
Before:
|
0 1 2 3 4 5 6 7 8 9 10 |
10 balance -2 \ 15 \ 20 |
After Left Rotation:
|
0 1 2 3 4 5 6 7 8 |
15 / \ 10 20 |
LR & RL Cases – Double Rotations
LR case (Left-Right):
|
0 1 2 3 4 5 6 7 8 9 10 |
10 balance +2 / 5 left child balance = -1 \ 7 |
Steps:
- Left rotate on left child (5 → 7 becomes root of left subtree)
- Right rotate on original node (10)
Result:
|
0 1 2 3 4 5 6 7 8 |
7 / \ 5 10 |
RL case is symmetric: right rotate first on right child, then left rotate on original node.
AVL Tree Node with Height
|
0 1 2 3 4 5 6 7 8 9 10 11 |
class AVLNode: def __init__(self, val): self.val = val self.left = None self.right = None self.height = 1 |
Helper functions
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
def height(node): return node.height if node else 0 def getBalance(node): return height(node.left) - height(node.right) if node else 0 def updateHeight(node): node.height = 1 + max(height(node.left), height(node.right)) |
Insert in AVL Tree (with balancing)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
def insert(root, val): if not root: return AVLNode(val) if val < root.val: root.left = insert(root.left, val) elif val > root.val: root.right = insert(root.right, val) else: return root # no duplicates # Update height updateHeight(root) # Get balance factor balance = getBalance(root) # Left Left Case if balance > 1 and val < root.left.val: return rightRotate(root) # Right Right Case if balance < -1 and val > root.right.val: return leftRotate(root) # Left Right Case if balance > 1 and val > root.left.val: root.left = leftRotate(root.left) return rightRotate(root) # Right Left Case if balance < -1 and val < root.right.val: root.right = rightRotate(root.right) return leftRotate(root) return root |
Why AVL Trees are still important (2025–2026 context)
| Advantages | When to prefer AVL |
|---|---|
| Strict O(log n) worst-case operations | When worst-case guarantee is critical |
| Predictable performance | Real-time systems, databases |
| Used in many libraries internally | Some language implementations |
| Excellent teaching tool | Understand self-balancing concept |
Disadvantages compared to Red-Black:
- More rotations (especially during insertion/deletion)
- Slightly more complex code
- Red-Black trees usually perform better in practice (fewer rotations)
Summary – AVL Tree in one line each
- Self-balancing Binary Search Tree
- Balance factor of every node = −1, 0, or +1
- Uses rotations (LL, LR, RR, RL) to maintain balance
- Guarantees O(log n) time for search, insert, delete in worst case
- In-order traversal → sorted order
- Most important to understand rotations and balance factor
- Classic interview topic to test recursion, tree manipulation, and balancing logic
Would you like to go deeper into any part?
Very common next topics:
- Step-by-step rotation examples (LL, LR, RR, RL) with multiple cases
- AVL Tree insert dry run with balancing
- AVL vs Red-Black Tree detailed comparison
- Delete operation in AVL Tree
- Is AVL Tree still used in 2026? (real-world usage)
Just tell me which direction you want — I’ll continue in the same detailed, teacher-style with drawings and examples! 😊
