AVL Tree
Context: FIT2004_MOC · the self-balancing BST — same search/insert/delete, plus a rebalance pass that caps the height at · siblings in W10: 2-3 Tree, Left-Leaning Red-Black Tree Parent Framework: Binary Search Tree (BST)
Quick Revision
- 🎯 Objective: BST the height-balance invariant at every node ➔ height ⟹ search, insert, delete all worst case (a plain BST degrades to ).
- 📦 Core Components: plain BST op ➔ update heights bottom-up along the path ➔ first node with ➔ trinode restructure (LL/RR single rotation, LR/RL double) ➔ keep climbing.
- ⚡ Key Constraint: classify by walking twice toward the taller side from the imbalanced node; if the second step is a tie (only happens on delete), repeat the first direction ⟹ single rotation, never double.
📝 How It Works
1. Height and Balance Factor
- Lecture height convention ➔ empty , leaf , node . Annotate every node by hand as
h,bf(the slides’ format). - Balance factor ➔ · positive ⟹ left taller · negative ⟹ right taller.
- AVL ⟺ at every node — recursive, like the BST definition (“true for each subtree as well”).
- Convention-proof ➔ Ian’s hand heights (leaf ) are not the textbook height; applied P8 counts a lone node as height . is a difference, so it is identical under either convention.
2. Operations = BST + Rebalance
- Search ➔ identical to BST.
- Insert ➔ BST insert, only at a leaf.
- Delete ➔ only at a leaf; a non-leaf key is first swapped with its in-order predecessor (biggest in left subtree) or successor (smallest in right subtree) — follow the question, be able to do both (they can trigger different rotations ➔ trace step 9).
- Rebalance ➔ walk back up the touched path, updating stored heights; the moment a node is imbalanced, restructure it; repeat until the root (“repeat until balanced” — a delete can cascade).
3. The Four Imbalance Cases
| Case | Taller child’s | Fix | |
|---|---|---|---|
| LL | rotate right at | ||
| RR | rotate left at | ||
| LR | rotate left at child ⟹ LL ⟹ rotate right at | ||
| RL | rotate right at child ⟹ RR ⟹ rotate left at |
- Child ➔ only arises after a delete; it is the “tie ⟹ follow the first traversal” rule, i.e. LL/RR.
4. Ian’s Way — Trinode Restructure (the PT-03 shortcut)
- Find ➔ the lowest node with or .
- Two steps down the taller side ➔ gives the other two nodes; tie on step 2 ⟹ go the same way as step 1.
- Median of the three keys ➔ new subtree root · smaller ➔ its left child · bigger ➔ its right child.
- Hang the four leftover subtrees back in in-order (left-to-right) — BST ordering is preserved automatically.
- Why one recipe covers all four cases ➔ every case ends in the same shape (diagram right-hand side); only which node is the median changes.
.png)
⚖️ Complexity
| Operation | Time | Why |
|---|---|---|
| Search | height , unchanged BST walk | |
| Insert / delete | descent bottom-up check each restructure rotations , at most one per level | |
| Space | one stored height per node; recursive implementation aux stack |
- Heights are stored, not recomputed ➔ recomputing from scratch, as done by hand, would cost ; updating only the path is what keeps rebalancing .
Why the Height Is — applied P8 [D]
- Sparsest AVL tree ➔ the fewest nodes at height has subtrees of heights and (equal heights would let one subtree drop its bottom level and stay AVL), each itself sparsest ⟹ , , .
- Closed form ➔ with ; strong induction: .
- Fibonacci floor ➔ ; induction step .
- Conclude ➔ any AVL tree with nodes and height has at least nodes:
⚖️ Core Decision Matrix
| Tree | Balance definition | Node shape | Rebalancing move | Delete in FIT2004 |
|---|---|---|---|---|
| AVL | per node | binary, height field | rotations (trinode restructure) | ✅ |
| 2-3 Tree | all leaves on the same level | 2-node / 3-node | split promote · merge / rotate | ✅ |
| LLRB | equal black edges on every root-to-leaf path | binary, colour bit | rotate colour flip | ❌ insert only |
When It Flips: need plain binary nodes and the tightest height rule ➔ AVL. Need the simplest balance statement (perfectly level leaves) ➔ 2-3. Need the 2-3 guarantee with binary nodes and unchanged BST search code ➔ LLRB, its binary encoding.
📊 Exam Execution Trace & Applied Exercises
Manual Execution Trace — insert 50 40 30 60 70 55 35, then delete 40 30 35
| Step | Op | () | Two steps | Case ➔ median | Tree after |
|---|---|---|---|---|---|
| 1–2 | ins 50, 40 | — | — | — | 50(40,_) |
| 3 | ins 30 | L, L | LL ➔ | 40(30,50) | |
| 4 | ins 60 | — | — | — | 40(30,50(_,60)) |
| 5 | ins 70 | R, R | RR ➔ | 40(30,60(50,70)) | |
| 6 | ins 55 | R to 60, L to 50 | RL ➔ | 50(40(30,_),60(55,70)) | |
| 7 | ins 35 | L to 30, R to 35 | LR ➔ | 50(35(30,40),60(55,70)) | |
| 8 | del 40, 30 | — | — | leaves, still balanced | 50(35,60(55,70)) |
| 9 | del 35 | R to 60, tie ⟹ R | RR ➔ | 60(50(_,55),70) |
- Step 6 subtrees ➔ , (50’s left), (50’s right), — moves from under to under .
- Step 9 tie ➔ ‘s children both have height ; going L would wrongly do a double rotation. () becomes ‘s right child.
- Then delete 60 ➔ predecessor :
55(50,70), no imbalance · successor :70(50(_,55),_)is LR at ➔55(50,70). Same tree, different work. - Prep P1 ➔ insert into
50(20(10,_),55(52,60)): is at while the root is only ⟹ fix , LL, median ➔50(10(5,20),55(52,60)). The solution’s “rotate the node 10” means rises to the subtree root. - Applied P1 ➔ insert into
3(2(1,_),8(5(4,7),9)): both () and () are imbalanced ⟹ fix the lower one, : L to (), R to ⟹ LR, median ➔3(2(1,_),7(5(4,6),8(_,9))). The root is balanced again without being touched — the reason rotations always start low.
✍️ Practice
Practice 1: Insert
10, 20, 30, 25, 28into an empty AVL tree. Name each imbalance and give the final tree.
- Hint: After
30, which two steps from the root? After28, where is the lowest imbalanced node?Answer
- ins 30 ➔ , R, R ⟹ RR ➔
20(10,30).- ins 25, 28 ➔
20(10,30(25(_,28),_)): has (lowest), L to , R to ⟹ LR, median ➔20(10,28(25,30)).- Why: Lowest first ➔ the root is also before the fix, but restructuring at restores its height and the root is balanced again.
Practice 2 (cascade): From
19(12(9(1,_),15(13,18(17,_))),28(22(20,_),29)), delete29.
- Hint: Fix the lowest imbalance, then recheck every ancestor.
Answer
- Fix 1 ➔ , L, L ⟹ LL, median ➔
22(20,28); the subtree’s height drops .- Fix 2 ➔ now : L to (), R to ⟹ LR, median ;
9(1,_), ,18(17,_),22(20,28).- Final ➔
15(12(9(1,_),13),19(18(17,_),22(20,28))).- Why: Deletes shorten subtrees ➔ a restructure after a delete can lower the height and expose an imbalance higher up, so the walk must continue to the root.
Practice 3 (applied P4): has , left subtree , right child (); has left child (, subtrees , ) and right subtree . All are AVL. Prove the RL rotation yields an AVL tree.
- Hint: Fix and read every other height off the balance factors.
Answer
- Heights ➔ ⟹ is , is · ⟹ is , is · ⟹ is .
- After RL ➔
y(x(ST1,ST2), z(ST3,ST4)): all four subtrees height ⟹ , both height ⟹ .- Why: Every node checked ➔ have and every node inside is unchanged and AVL by assumption ⟹ all .
⚠️ Common Mistakes
- 💡 Restructuring the highest imbalanced node ➔ always fix the lowest one first, then move up.
- 💡 Choosing the second step by key instead of height ➔ step toward the taller subtree, not toward the inserted key’s side after a delete.
- 💡 Dropping / ➔ the middle subtrees change parent; re-hang all four in in-order and recheck heights.
🧠 Active Recall
Why is AVL insert even though checking balance by hand means recomputing every height?
Answer
- Short answer: the implementation stores heights and only updates the nodes on the touched path.
- Why: Path length ➔ by the invariant; each node update is from its children’s stored heights; each restructure is rotations ⟹ . Recomputing from scratch would be .
After a delete, the child on the taller side has . Single or double rotation, and why?
Answer
- Short answer: single — follow the first direction again (LL or RR).
- Why: Shape ➔ with both grandchildren equally tall, rotating once at already balances; a double rotation would lift the wrong grandchild and leave elsewhere.