ITC 120 › Midterm › Balanced trees
Balanced trees · Lesson 1 of 2
AVL Trees
This lesson teaches:Data structureAlgorithmA binary search tree that fixes its own shape, so searching stays fast.
By the end, you can:
- explain why a BST built from sorted values is slow, using its height, and compare the time of search and insert in a balanced tree (about log₂ n steps) and an unbalanced one (up to n steps);
- compute the height and balance factor (left − right) of any node;
- name the case at an unbalanced node (LL, RR, LR, RL) and fix it with the right rotation(s);
- insert a list of values into an AVL tree by hand and write its traversals, the way the exam asks;
- point to the lines in the Java
insertRecthat update heights and fix each case.
You need: the BST lessons (insertion and traversals), scratch paper, and a pen.
Part 1 · The problem
Why a BST can become slow
Recall how BST search works: at each node, you compare and go left (smaller) or right (larger). Each comparison takes you one level down. So the number of comparisons depends on how tall the tree is.
But the shape of a BST depends on the order you insert the values. Below are the same seven values, 10 to 70, inserted in two different orders. Both trees follow the BST rule. Count the comparisons needed to find 70 (the shaded nodes):
Same values, different shapes
Inserted in sorted order: 10, 20, 30, 40, 50, 60, 70
height 6 Finding 70 takes 7 comparisons.
Inserted in mixed order: 40, 20, 60, 10, 30, 50, 70
height 2 Finding 70 takes only 3 comparisons.
The first tree is really just a linked list wearing a tree costume. With 1,000 values inserted in sorted order, a search could need 1,000 comparisons. A well-shaped tree with 1,000 values needs only about 10.
How fast? Balanced vs. unbalanced
Search, insert, and delete each walk one path down the tree, so their work grows with the tree's height. Here is how the number of steps grows with n, the number of values:
| Tree | Height with n values | 1,000 values | 1,000,000 values |
|---|---|---|---|
| Unbalanced BST (worst case: a chain) | about n | up to 1,000 steps | up to 1,000,000 steps |
| Balanced tree (AVL, red-black) | close to log₂ n | about 10 steps | about 20 steps |
Where does "about 10" come from? In a balanced tree, each level can hold twice as many nodes as the level above it: 1, 2, 4, 8, 16, and so on. A search walks one path down, one node per level, so its number of steps is the number of levels:
10 levels hold about 1,000 nodes, and 20 levels hold about 1,000,000. So in a balanced tree, a search takes about 10 steps for 1,000 values and about 20 steps for a million.
Books call this number of levels log₂ n ("log base 2 of n"): how many times you can cut n in half until you reach 1. Watch 1,024 get cut in half, again and again:
That is why balanced trees stay fast: doubling the number of values adds only one more level (one more cut). 2,000 values need about 11 steps, not 2,000.
Keeping the tree balanced does not slow things down either: the fix it uses, a rotation (you will learn it in Part 4), changes only a few links.
Good to know: books write the two speeds as O(n) ("order n") for the unbalanced worst case and O(log n) ("order log n") for a balanced tree. An AVL tree can be a little taller than log₂ n, but never much: at most about 1.44 × log₂ n. So even a million values need fewer than 30 steps.
Where you see this in IT
Sorted input is very common: student ID numbers given out in order, receipts numbered 0001, 0002, 0003, or records saved with the date and time. Insert any of these into a plain BST and you get the slow chain.
Think of a pedicab
A Mati pedicab has a front seat beside the driver and two benches at the back. If the back is full and the front is empty, the pedicab tilts backward: its bottom can nearly scrape the road, and the back wheels carry too much weight (worse in older pedicabs). So the driver asks a passenger to move to the front seat. Nobody gets off; they just change seats.
An AVL tree does the same thing. When one side gets too heavy, it moves a few nodes around (a rotation). No value is removed, and the BST rule still holds.
Part 2 · Measuring the lean
Height and balance factor
A node leans when one of its sides goes down further than the other, like the pedicab in Part 1 that tilts when one end is heavier. A tree leans when some of its nodes lean too much. Here are a node that leans and a node that does not:
10 leans right: its right side goes two levels down, its left side is empty.
20 does not lean: both sides go one level down.
To measure how much a node leans, we need a number for each node. That number is built from height, which you learned in the Trees lesson (quick review in the box below).
Height (review)
The height of a node is the number of edges on the longest path from that node down to a leaf .
A leaf has height 0. An empty spot (a null child) has height −1, because it is one level below a leaf.
Balance factor
The balance factor of a node is the height of its left subtree minus the height of its right subtree:
balance factor = height(left) − height(right)
Work it out for every node, one node at a time, in three steps:
- Find the height of the node's left subtree (that is, the height of its left child). No left child? Use −1.
- Find the height of its right subtree the same way. No right child? Use −1.
- Subtract: left − right.
Do not mix up the two numbers. A node's height says how tall its own subtree is. Its balance factor compares its two sides. In the pictures below, h= under a node is its height, and the small number at its top right is its balance factor .
The sign of the balance factor tells you which way the node leans. There are three possible readings:
| Balance factor | Meaning |
|---|---|
| positive (+1, +2, …) | The left side is taller. |
| 0 | Both sides are the same height. |
| negative (−1, −2, …) | The right side is taller. |
The balance rule
A node is balanced if its balance factor is −1, 0, or +1.
It is unbalanced when it reaches +2 or −2. That is when an AVL tree (the self-fixing tree from Part 1 ) must fix it.
Example: work it out
Look at node 20: its left child 10 has height 0, and its right child 30 has height 0. So its balance factor is 0 − 0 = 0.
Look at node 40: its left subtree (starting at 20) has height 1. Its right subtree (starting at 60) has height 0. So 1 − 0 = +1. It leans left a little, but that is allowed.
Look at leaf 60: both children are empty (height −1). So −1 − (−1) = 0. Every leaf has balance factor 0.
Example 2: a missing child counts as −1
Insert 10, 20, 30 into a plain BST. You get this chain (you will meet it again in Part 4 as the RR case):
Work from the bottom up. The table shows each node's left height, right height, and balance factor:
| Node | Left subtree height | Right subtree height | Balance factor |
|---|---|---|---|
| 30 | −1 (no left child) | −1 (no right child) | −1 − (−1) = 0 |
| 20 | −1 (no left child) | 0 (30 is a leaf) | −1 − 0 = −1 |
| 10 | −1 (no left child) | 1 (20 → 30 is one edge) | −1 − 1 = −2 |
Node 10 is −2: unbalanced, because its right side is two levels taller than its left. Notice that 10's balance factor (−2) is not its height (2): the height measures one side going down, the balance factor compares two sides.
Try it: tap any node
Tap a node to work out its balance factor. Find every node that is unbalanced (balance factor of +2 or more, or −2 or less).
Tap a node above.
Exam traps
- It is left minus right, not right minus left. Getting the order wrong flips every sign.
- It uses heights, not the number of nodes.
- Check every node. A tree can be fine at the root but unbalanced lower down (like 60 in the explorer above: −2, while the root 40 is 0).
Part 3 · The idea
What an AVL tree is
AVL tree
An AVL tree is a binary search tree in which every node has a balance factor of −1, 0, or +1. After every insertion or deletion, it checks the balance factors and uses rotations to fix any node that reaches ±2.
So an AVL tree follows two rules at the same time:
- The BST rule: smaller values to the left, larger values to the right.
- The balance rule: every node's balance factor is −1, 0, or +1.
It is named after the two people who invented it in 1962, G. M. Adelson-Velsky and E. M. Landis. It was the first self-balancing binary search tree.
Exam trap
An AVL tree is not perfectly balanced. Small differences (±1) are allowed. It does not rotate after every insert, only when a node reaches ±2.
Part 4 · The fix
Rotations
A rotation is a small rearrangement of a node and one of its children. One goes up, the other goes down, and the shape changes. The BST rule still holds afterwards, so the in-order list stays the same.
A right rotation, slowly
Here is a tree that needs a fix. 10 was just inserted, and now 40 has a balance factor of +2: its left side is two levels taller than its right. A right rotation at 40 fixes it in three moves:
- 30 moves up into 40's old spot.
- 40 moves down to become 30's right child.
- But 30's right spot already held 35. Now 40 is there, so 35 is left floating and needs a new spot. It goes to 40's left, which is empty (40 lost its left child, 30, in move 1).
1. Before: 40 is +2 (too tall on the left)
2. 30 up, 40 down: 35 is floating
3. After: 35 is 40's left child, and every node is balanced
Why 40's left, and nowhere else? Find 35's spot the same way as BST insertion : 35 is bigger than 30, so go right to 40; 35 is smaller than 40, so look left: empty, so 35 goes there. It is the only spot that keeps the BST rule, so there is exactly one correct place.
In the Java code (Part 7), 35 is not inserted again from the top. One line moves it, together with anything under it, straight to 40's left. It lands in the same spot.
Check: the in-order list before is 10, 20, 30, 35, 40, 50. After, it is still 10, 20, 30, 35, 40, 50. And the balance factors are back in −1 to +1.
A left rotation
A left rotation is the same three moves with left and right swapped. Here, 50 was just inserted, and 20 has a balance factor of −2: its right side is two levels taller. A left rotation at 20 fixes it:
- Its right child, 30, moves up into 20's spot.
- 20 moves down to become 30's left child.
- 30's old left child, 25, moves to 20's empty right spot (25 is bigger than 20 and smaller than 30).
Before: 20 is −2 (too tall on the right)
After left rotation at 20
Check: the in-order list is 10, 20, 25, 30, 40, 50 before and after, and every balance factor is back in −1 to +1.
The four cases
When a node becomes unbalanced, we look at the path from that node toward the value we just inserted. The first two moves on that path give the case its name. There are four types of cases:
| Case | Path from the unbalanced node | Shape | Fix |
|---|---|---|---|
| LL | left, then left | straight line | 1 right rotation at the unbalanced node |
| RR | right, then right | straight line | 1 left rotation at the unbalanced node |
| LR | left, then right | zigzag | left rotation at the child, then right rotation at the unbalanced node |
| RL | right, then left | zigzag | right rotation at the child, then left rotation at the unbalanced node |
In the small trees: red = the unbalanced node (±2), orange = the value just inserted.
Why a zigzag needs two rotations
Take the LR case: insert 30, 10, 20. The path from 30 goes left, then right: a zigzag. One right rotation at 30 does not work here: it only flips the zigzag the other way, and the tree is still unbalanced.
So the fix starts one level lower, at the child 10. Rotation 1 is a normal left rotation , only done at 10: 20 (10's right child) moves up into 10's spot, and 10 moves down to become 20's left child. With just two nodes, it looks like 20 and 10 swapped places, but it is the same three moves. The BST rule decides the result: 10 < 20 < 30, so after the rotation the three values sit in a straight line going left. That is the LL case, and LL needs one right rotation:
1. Zigzag (LR): 30 is +2
2. Left rotation at 10: now a straight line (LL)
3. Right rotation at 30: balanced
RL is the same with left and right swapped: a right rotation at the child, then a left rotation at the unbalanced node. The panel below shows all four cases step by step.
Watch each case
Pick a case, then tap Next step. Each example inserts three values into an empty tree.
Color key
Notice that all four examples end with the same tree: 20 at the top, 10 on the left, 30 on the right. Different starting shapes, same balanced result.
How to remember
Straight line → 1 rotation. Zigzag → 2 rotations.
For LL and RR, rotate the opposite way: too heavy on the left, rotate right. For LR and RL, the first rotation straightens the zigzag into a line, then you fix the line.
Part 5 · Putting it together
Inserting, step by step
Every AVL insertion follows the same four steps. This is the procedure you will use in the exam:
- Insert the value like a normal BST. It becomes a new leaf.
- Check balance factors, starting from the new leaf and going up to the root.
- At the first node that reaches +2 or −2, name the case (LL, RR, LR, or RL) using the path toward the new value.
- Rotate using the fix for that case. One fix is enough: the whole tree is balanced again.
If no node reaches ±2 in step 2, there is nothing to fix. Move on to the next value.
Worked example: all four cases
This list triggers LL, LR, RR, and RL. Tap Next step and say the next move out loud before you tap. Then try your own numbers.
Color key
Doing it on paper
- Redraw the whole tree after every insertion that causes a rotation. Do not erase and squeeze.
- Write the balance factor beside each node on the path you just walked.
- Before rotating, write the case name (for example, "LR at 65"). It keeps you from rotating the wrong way.
- After rotating, do a quick in-order check: the list must still be sorted.
Exam traps
- Name the case from the unbalanced node, not from the root.
- Fix only the lowest unbalanced node (closest to the new value). After that one fix (one or two rotations), the nodes above it are balanced too. This is true for insertion; deleting a value can need more fixes higher up.
- Do not forget the child that changes parent during a rotation. Losing it is the most common mistake.
Part 6 · Your turn
Try it on paper
The exam asks you to build an AVL tree and then traverse it. Do each problem on paper before opening the answer. Then check yourself with the lab in Part 5 by typing in the same numbers.
Problem 1
Insert these values, in order, into an empty AVL tree:
21, 9, 15, 5, 30, 26, 23
Then write the pre-order, in-order, and post-order traversals of your final tree.
Show the answer
Two fixes. Inserting 15 makes 21 unbalanced (+2): the LR case (left rotation at 9, then right rotation at 21). Inserting 26 makes 21 unbalanced (−2). From 21 the path went right (30), then left (26): the RL case (right rotation at 30, then left rotation at 21). Inserting 23 needs no fix.
| Pre-order | 15, 9, 5, 26, 21, 23, 30 |
|---|---|
| In-order | 5, 9, 15, 21, 23, 26, 30 |
| Post-order | 5, 9, 23, 21, 30, 26, 15 |
Problem 2
Insert these values, in order, into an empty AVL tree:
1, 2, 3, 4, 5, 6, 7
Then write the pre-order, in-order, and post-order traversals of your final tree.
Show the answer
Four fixes, all the RR case (one left rotation each): when inserting 3 (at 1), 5 (at 3), 6 (at 2, the root), and 7 (at 5). Sorted input that made a chain in a plain BST becomes a perfectly bushy tree.
| Pre-order | 4, 2, 1, 3, 6, 5, 7 |
|---|---|
| In-order | 1, 2, 3, 4, 5, 6, 7 |
| Post-order | 1, 3, 2, 5, 7, 6, 4 |
Problem 3
Insert these values, in order, into an empty AVL tree:
50, 30, 70, 20, 40, 35
Then write the pre-order, in-order, and post-order traversals of your final tree.
Show the answer
One fix. Inserting 35 makes 50 unbalanced (+2). From 50 the path went left (30), then right (40): the LR case. Left rotation at 30, then right rotation at 50. Watch 35: it changes parent and ends up as the right child of 30.
| Pre-order | 40, 30, 20, 35, 50, 70 |
|---|---|
| In-order | 20, 30, 35, 40, 50, 70 |
| Post-order | 20, 35, 30, 70, 50, 40 |
Part 7 · In code
AVL insertion in Java
The Java version is your insertRec from the Recursion lesson, plus a few small methods. The node gets one new field, height, so we do not have to count the height again every time.
1. The node remembers its height
class TreeNode {
int data;
int height; // NEW: height of this node
TreeNode left;
TreeNode right;
TreeNode(int value) {
data = value;
height = 0; // a new node is a leaf
}
} 2. Three small helpers
// height of a node; an empty spot is -1
static int height(TreeNode node) {
if (node == null) {
return -1;
}
return node.height;
}
// recompute height from the two children
static void updateHeight(TreeNode node) {
node.height = 1 + Math.max(height(node.left),
height(node.right)); // the bigger one
}
// balance factor = left height - right height
static int balance(TreeNode node) {
return height(node.left) - height(node.right);
} These match Part 2 exactly: a leaf is 0, an empty spot is −1, and the balance factor is left minus right.
3. The right rotation
static TreeNode rotateRight(TreeNode z) {
TreeNode y = z.left; // y will move up
TreeNode moved = y.right; // changes parent
y.right = z; // z goes down, right
z.left = moved;
updateHeight(z); // z first: it is lower now
updateHeight(y);
return y; // y is the new top
} Compare rotateRight with the right rotation picture in Part 4 : z is 40, y is 30, and moved is 35. The method returns the new top, so whoever called it can connect it back to the tree.
rotateLeft is the same code with every left and right swapped (a mirror image), and insertRec below calls it too. You will write it yourself in the coding task at the end of this part.
4. Insert, then fix on the way back up
static TreeNode insertRec(TreeNode node, int value) {
// Step 1: normal BST insert
if (node == null) {
return new TreeNode(value);
}
if (value < node.data) {
node.left = insertRec(node.left, value);
} else if (value > node.data) {
node.right = insertRec(node.right, value);
} else {
return node; // duplicate: do nothing
}
// Step 2: update height, check balance
updateHeight(node);
int b = balance(node);
// Steps 3-4: name the case and rotate
if (b > 1 && value < node.left.data) { // LL
return rotateRight(node);
}
if (b < -1 && value > node.right.data) { // RR
return rotateLeft(node);
}
if (b > 1 && value > node.left.data) { // LR
node.left = rotateLeft(node.left);
return rotateRight(node);
}
if (b < -1 && value < node.right.data) { // RL
node.right = rotateRight(node.right);
return rotateLeft(node);
}
return node; // balanced: nothing to fix
} You call it the same way as before: root = insertRec(root, 25);
Why "on the way back up" works
Recursion goes down to find the spot, then each call finishes in reverse order, from the new leaf back up to the root. That is exactly step 2 of the procedure: check from the new node upward. The first call to find b equal to 2 or −2 is the lowest unbalanced node, and it fixes itself before returning.
How does the code name the case? b > 1 means the left side is too tall (first letter L). Then value < node.left.data means the new value went left again (second letter L), and so on.
Your coding task: write rotateLeft
A left rotation fixes the RR case, when the right side is too tall. Look at a left rotation : z is 20, y is 30, and moved is 25. y moves up, z goes down to the left, and moved changes parent. In code, it is rotateRight with every left and right swapped.
Write rotateLeft in about 7 lines where it says YOUR CODE. The rest of the program is the code from this part: rotateRight, the three helpers, and insertRec, which calls rotateLeft in the RR, LR, and RL cases. Each test prints a tree's pre-order and its height. Run it: each printed line must match its comment.
1public class Main {
2 // The mirror image of rotateRight: z's right child y moves up,
3 // z goes down to the left. Returns y, the new top.
4 static TreeNode rotateLeft(TreeNode z) {
5 // YOUR CODE (mirror rotateRight: swap every left and right):
6 // 1. y is z's right child. moved is y's left child.
7 // 2. z becomes y's left child.
8 // 3. moved becomes z's right child.
9 // 4. Update the heights: z first (it is lower now), then y.
10 // 5. Return y.
11
12 return z;
13 }
14
15 // Given: everything below is from this lesson.
16 static TreeNode rotateRight(TreeNode z) {
17 TreeNode y = z.left;
18 TreeNode moved = y.right;
19 y.right = z;
20 z.left = moved;
21 updateHeight(z);
22 updateHeight(y);
23 return y;
24 }
25
26 static int height(TreeNode node) {
27 if (node == null) {
28 return -1;
29 }
30 return node.height;
31 }
32
33 static void updateHeight(TreeNode node) {
34 node.height = 1 + Math.max(height(node.left),
35 height(node.right));
36 }
37
38 static int balance(TreeNode node) {
39 return height(node.left) - height(node.right);
40 }
41
42 static TreeNode insertRec(TreeNode node, int value) {
43 if (node == null) {
44 return new TreeNode(value);
45 }
46 if (value < node.data) {
47 node.left = insertRec(node.left, value);
48 } else if (value > node.data) {
49 node.right = insertRec(node.right, value);
50 } else {
51 return node;
52 }
53 updateHeight(node);
54 int b = balance(node);
55 if (b > 1 && value < node.left.data) { // LL
56 return rotateRight(node);
57 }
58 if (b < -1 && value > node.right.data) { // RR
59 return rotateLeft(node);
60 }
61 if (b > 1 && value > node.left.data) { // LR
62 node.left = rotateLeft(node.left);
63 return rotateRight(node);
64 }
65 if (b < -1 && value < node.right.data) { // RL
66 node.right = rotateRight(node.right);
67 return rotateLeft(node);
68 }
69 return node;
70 }
71
72 static void preOrder(TreeNode node) {
73 if (node == null) { return; }
74 System.out.print(node.data + " ");
75 preOrder(node.left);
76 preOrder(node.right);
77 }
78
79 static TreeNode build(int[] values) {
80 TreeNode root = null;
81 for (int i = 0; i < values.length; i++) {
82 root = insertRec(root, values[i]);
83 }
84 return root;
85 }
86
87 public static void main(String[] args) {
88 // RR at 10. Expected: 20 10 30 height 1
89 TreeNode a = build(new int[] {10, 20, 30});
90 preOrder(a);
91 System.out.println("height " + a.height);
92
93 // RL at 10. Expected: 20 10 30 height 1
94 TreeNode b = build(new int[] {10, 30, 20});
95 preOrder(b);
96 System.out.println("height " + b.height);
97
98 // Four RR cases. Expected:
99 // 40 20 10 30 60 50 70 height 2
100 TreeNode c = build(new int[] {10, 20, 30, 40, 50, 60, 70});
101 preOrder(c);
102 System.out.println("height " + c.height);
103
104 // RL at 20, below the root. Expected:
105 // 50 25 20 30 70 height 2
106 TreeNode d = build(new int[] {50, 20, 70, 30, 25});
107 preOrder(d);
108 System.out.println("height " + d.height);
109 }
110}
111
112class TreeNode {
113 int data;
114 int height;
115 TreeNode left;
116 TreeNode right;
117
118 TreeNode(int value) {
119 data = value;
120 height = 0;
121 }
122} ▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.
Show one possible answer
1static TreeNode rotateLeft(TreeNode z) {
2 TreeNode y = z.right;
3 TreeNode moved = y.left;
4 y.left = z;
5 z.right = moved;
6 updateHeight(z);
7 updateHeight(y);
8 return y;
9} Output, one per line: 20 10 30 height 1, 20 10 30 height 1, 40 20 10 30 60 50 70 height 2, 50 25 20 30 70 height 2.
Put it beside rotateRight: z.left became z.right, and y.right became y.left. The two updateHeight lines stay the same, in the same order.
The tests reach rotateLeft in different ways. 10, 20, 30 is the RR case: one left rotation at 10. 10, 30, 20 is the RL case: a right rotation at 30, then a left rotation at 10. Inserting 10 to 70 in order needs four left rotations, the same as Problem 2, and ends as a perfect tree of height 2. The last test rotates at 20, below the root: the new top, 25, is returned and saved as 50's left child.
A common mistake is updating y before z. Then y's height is counted from z's old height, from when z was on top, so it comes out too big. The first test prints 20 10 30 height 3 for a tree of only three nodes. Wrong heights give wrong balance factors, so later rotations go wrong too: 10 to 70 ends as 60 40 20 10 30 50 70 height 5. Update z first, because it is lower now and y's height depends on it.
Part 8 · Check yourself
Self-check
Not graded. Tap an answer to see if you got it, and read why. Try again until you get them all.
-
The balance factor of a node is computed as:
Balance factor = height(left) − height(right). It uses heights, not node counts, and it is left minus right.
-
In an AVL tree, a node is unbalanced when its balance factor becomes:
−1, 0, and +1 are allowed. When an insertion makes a node reach +2 or −2, the tree must rotate.
-
Which statement about AVL trees is true?
AVL trees allow small differences (±1), so they are not perfectly balanced. They rotate whenever an insert or delete makes a node reach ±2.
-
You insert 30, then 20, then 10 into an empty AVL tree. Which case is this, and what is the fix?
From 30, the new value went left (20), then left (10): LL. A straight line to the left is fixed with one right rotation at 30. The new root is 20.
-
You insert 10, then 30, then 20. Which case is this?
From 10, the new value went right (to 30), then left (to 20). Right, then left: RL. It is a zigzag, so it needs two rotations: right at 30, then left at 10.
-
After an insertion, two nodes have balance factor +2: one is the root, the other is lower down, closer to the new value. Which one do you fix?
Fix the first unbalanced node you meet going up from the new value. After that one fix, the nodes above it become balanced too.
-
During a right rotation at node z (its left child is y), what happens to y's right child?
y moves up and z moves down to y's right. y's old right child cannot stay (that spot now holds z), so it moves over to become z's left child. It still fits the BST rule there.
-
A plain BST and an AVL tree each get the values 1 to 1,000,000, inserted in sorted order. About how many steps can one search need in each?
Sorted input makes the plain BST a chain, so a search can pass every value: up to n steps, O(n). The AVL tree stays balanced, so its height grows like log₂ n: about 20 for a million values, O(log n). See How fast? in Part 1.
-
Which traversal of any AVL tree gives the values in sorted order?
An AVL tree is still a BST, and rotations never break the BST rule. So in-order (Left, Node, Right) is always sorted.
Score: 0 / 9
Key takeaways
- A BST can become a slow chain if values arrive in sorted order: up to n steps per search. A balanced tree needs only about log₂ n.
- Balance factor = height(left) − height(right). Allowed: −1, 0, +1. Fix at ±2.
- An AVL tree is a BST that keeps every balance factor in −1 to +1 using rotations.
- Name the case from the unbalanced node: LL and RR need 1 rotation; LR and RL need 2.
- During a rotation, one child changes parent. Don't lose it.
- Rotations never break the BST rule, so in-order is always sorted.
Next lesson: Red-black trees, another way to keep a BST balanced.
References
- G. M. Adelson-Velsky and E. M. Landis, "An algorithm for the organization of information," Soviet Mathematics Doklady, vol. 3, pp. 1259–1263, 1962.
- Programiz, "AVL Tree." programiz.com/dsa/avl-tree
- T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein, Introduction to Algorithms, 4th ed. MIT Press, 2022 (rotations, Section 13.2).