0% found this document useful (0 votes)
5 views23 pages

AVL Trees II

The document discusses AVL trees, which are a type of balanced binary search tree (BST) where the height difference between left and right subtrees is at most one. It explains how to measure tree height, balance, and the necessary rotations (left and right) to maintain AVL properties after insertions. Additionally, it provides code snippets for implementing AVL tree operations and highlights the importance of tracking node heights during these operations.

Uploaded by

therealmystical
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views23 pages

AVL Trees II

The document discusses AVL trees, which are a type of balanced binary search tree (BST) where the height difference between left and right subtrees is at most one. It explains how to measure tree height, balance, and the necessary rotations (left and right) to maintain AVL properties after insertions. Additionally, it provides code snippets for implementing AVL tree operations and highlights the importance of tracking node heights during these operations.

Uploaded by

therealmystical
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 23

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”.

We can measure how balanced it is with the balance function:


balance(node) = height(node->right) - height(node->left)
1

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

iClicker: Begin with this BST that satisfies the


46
AVL balance property. Insert 95, and update
the heights. Is this still an AVL tree?
29 76
“Broken at” = lowest node with large balance

31 65 80 A) Yup, still an AVL tree


B) No, broken at 90
C) No, broken at 80
D) No, broken at 76
77 90 E) No, broken at 46 #cs251-sp24-lec-29
AVL Tree Insertion
Using plain BST insertion on an AVL tree can make it not an AVL tree!

After every insertion, must check and maybe fix.

#cs251-sp24-lec-29
Fixing BST Worst Case
h=2

h=1 1

h=0 insert(2) 1 insert(3) h=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!

struct AVLNode { int getHeight(AVLNode* n) {


int key; // nullptr check is annoying to repeat...
int height; if (n == nullptr) {
AVLNode* left; return -1;
AVLNode* right; }
}; return n->height; #cs251-sp24-lec-29
}
Tree Height Tracking
// Update heights going up the tree
void insert(int to_insert) {
while (!nodes.empty()) {
AVLNode* prev = nullptr;
curr = nodes.top();
AVLNode* curr = root;
nodes.pop();
stack<AVLNode*> 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).

What if 2 has a left child? Where should this go in the rotation?

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

void LeftRotate(AVLNode* parent, // Update parent pointers


AVLNode* a) { if (parent == nullptr) { // Update heights
// Rotate root = b; a->height = 1 + max(getHeight(x),
AVLNode* b = a->right; } else if (a->key < parent->key) { getHeight(y));
AVLNode* x = a->left; parent->left = b;
} else {
b->height = 1 + max(getHeight(a),
AVLNode* y = b->left;
parent->right = b; getHeight(z));
AVLNode* z = b->right;
}

a->right = y;
b->left = a;
Left Rotation, Large Demo

Insert 95, and update the heights. Perform a


46
left rotation to make it an AVL tree.

29 76

31 65 80

77 90 #cs251-sp24-lec-29
Left Rotation, Large Demo

Insert 95, and update the heights. Perform a


46
left rotation to make it an AVL tree.

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

Same rotation – other direction!


Right Rotations

3 2
2

2 3 1 3

1 1
Right Rotate Code
a b

b RightRotate(a) a

Y Z

Z X X Y

void RightRotate(AVLNode* parent, // Update parent pointers


AVLNode* a) { // Update heights
if (parent == nullptr) {
// Rotate // update root a->height = 1 + max(getHeight(x),
AVLNode* b = a->left; } else if (a->key < parent->key) { getHeight(y));
AVLNode* y = a->right; parent->left = b;
b->height = 1 + max(getHeight(a),
AVLNode* z = b->left; } else {
parent->right = b; getHeight(z));
AVLNode* x = b->right;
}

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.

iClicker: Which node is rotated, and what kind of rotation is it?

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

You might also like