AVL Trees II
AVL Trees II
CS 251
Semi-Review: Tree Height
● Height of a node: max # of edges from the node to a leaf
○ Max # of pointers to follow to get to a leaf
○ height(node) = 1 + max(height(node->left), height(node->right))
■ height(nullptr) = -1
46 2
6
3
29 76
4 #cs251-sp24-lec-29
17 31 99
5
Quantifying “Unbalanced-ness”
A BST can be “balanced”, or “unbalanced”.
46 2
6
3
29 76
#cs251-sp24-lec-29
4
17 31 99
5
AVL Trees
A tree is an AVL tree if it… root
22
● Is a BST:
○ For every node…
■ At most 2 children 11 64
■ All nodes in left subtree smaller
■ All nodes in right subtree greater
3 19 68
● Is balanced:
○ For every node…
■ The height of the left and right
subtrees differs by at most 1 10
#cs251-sp24-lec-29
Height of a node: max # of edges
from the node to a leaf
Height of nullptr is -1.
AVL Trees
A tree is an AVL tree if it… root
22
● Is a BST:
○ For every node…
■ At most 2 children 11 64
■ All nodes in left subtree smaller
■ All nodes in right subtree greater
3 19 68
● Is balanced:
○ For every node…
■ abs(balance(node)) ≤ 1
10
#cs251-sp24-lec-29
balance(node) =
height(node->right) -
height(node->left)
AVL Height Demo
This tree satisfies the AVL balance property. What happens when we insert 20?
46
29 76
17 31 99
#cs251-sp24-lec-29
AVL Balance: iClicker
#cs251-sp24-lec-29
Fixing BST Worst Case
h=2
h=1 1
1 h=0 2
insert(1)
h=0
2
3
Inserting 3 breaks the balance
h=2
condition at 1:
● Left child is nullptr, with h = 1 h=1
-1 h=1 fix(1) 2
● Right child is 2, with h = 1 2
h=0 h=0
● abs(-1 - 1) = 2 > 1
h=0
1 3
There’s a unique balanced tree 3
with 3 nodes!
Left Rotations
This “fix” is called a left rotation. We’re “rotating” the right child node “up” (and
moving the parent node to the left):
1 2 2
2 1 1 3
3 3
Tree Height Tracking
Heights are useful – probably good to store as a member variable and keep it
updated. On insert, need to go through and update affected nodes!
int leftHeight;
while (curr != nullptr) {
int rightHeight;
if (curr->key == to_insert) {
if (curr->left == nullptr) { leftHeight = -1; }
return; // already in the tree
else { leftHeight = curr->left->height; }
} else {
if (curr->right == nullptr) { rightHeight = -1; }
nodes.push(curr);
else { rightHeight = curr->right->height; }
// Advance down tree...
}
// If this height hasn’t changed, nodes above
}
// this won’t either - can stop!
int newHeight = max(leftHeight, rightHeight);
// New node with height 0, link in...
if (curr->height == newHeight) { break; } #cs251-sp24-lec-29
curr->height = newHeight;
}
}
Left Rotations
This “fix” is called a left rotation. We’re “rotating” the right child node “up” (and
moving the parent node to the left).
1 2 2
2 1 1 3
1.5
3 3 1.5
1.5
Left Rotations
This “fix” is called a left rotation. We’re “rotating” the right child node “up” (and
moving the parent node to the left):
b
a
LeftRotate(a) a
b
X Z
Y Z X Y
#cs251-sp24-lec-29
This is the fundamental operation of an AVL tree!
After lifting b up, this is the only way to correctly arrange the subtrees.
Also helpful to think of it like gravity, lifting b up, letting the other nodes fall,
and correcting pointers.
Left Rotate Code
b
a
LeftRotate(a) a
b
X Z
Y Z X Y
a->right = y;
b->left = a;
Left Rotation, Large Demo
29 76
31 65 80
77 90 #cs251-sp24-lec-29
Left Rotation, Large Demo
29 76
31 65 80
77 90 #cs251-sp24-lec-29
Another AVL Case
We’ve just inserted 16, and the AVL condition is broken at 22.
The left side has a greater height, so we should “lift it up” by moving 22 to the right.
15 15
8 22 8 19
fix(22)
4 10 19 24 4 10 17 22
3 6 17 3 6
20
16 20 24
16
3 2
2
2 3 1 3
1 1
Right Rotate Code
a b
b RightRotate(a) a
Y Z
Z X X Y
a->left = x;
b->right = a;
Worked Example
Inserting the values 1, 2, 5, 4, 3 in order into an initially empty AVL tree.
#cs251-sp24-lec-29
Your Turn
First, verify that this is an AVL tree. Then, insert 58. Does a rotation occur? If so, perform the rotation.
60
40 74
27 50 90
#cs251-sp24-lec-29
45 54
Up Next
We’ve handled 2 “bad” cases:
2 more to go! These will also use rotations, but need a bit more work.
#cs251-sp24-lec-29