Unit #7: AVL Trees
CPSC 221: Algorithms and Data Structures
Lars Kotthoff1 larsko@cs.ubc.ca
1With material from Will Evans, Steve Wolfman, Alan Hu, Ed Knorr, and
Kim Voll.
Unit #7: AVL Trees CPSC 221: Algorithms and Data Structures Lars - - PowerPoint PPT Presentation
Unit #7: AVL Trees CPSC 221: Algorithms and Data Structures Lars Kotthoff 1 larsko@cs.ubc.ca 1 With material from Will Evans, Steve Wolfman, Alan Hu, Ed Knorr, and Kim Voll. Unit Outline Binary search trees Balance implies shallow
Lars Kotthoff1 larsko@cs.ubc.ca
1With material from Will Evans, Steve Wolfman, Alan Hu, Ed Knorr, and
Kim Voll.
▷ Binary search trees ▷ Balance implies shallow (shallow is good) ▷ How to achieve balance ▷ Single and double rotations ▷ AVL tree implementation
▷ Compare and contrast balanced/unbalanced trees. ▷ Describe and apply rotation to a BST to achieve a balanced
tree.
▷ Recognize balanced binary search trees (among other tree
types you recognize, e.g., heaps, general binary trees, general BSTs).
Worst Case Runtime:
insert find delete (after find) Linked list Unsorted array Sorted array Hash table
2 4 5 7 8 9 12 14 17 20 21 25 2 4 5 7 8 12 14 17 20 21 25 2 4 7 8 4 8 12 14 20 21 25 20 25 14
int bSearch(int A[], int key, int i, int j) { if(j < i) return -1; int m = (i + j) / 2; if(key < A[m]) return bSearch(A, key, i, m-1); else if(key > A[m]) return bSearch(A, key, m+1, j); else return m; }
2 8 5 20 17 9 7 14 12 25 21 4
Binary tree property
▷ each node has ≤ 2 children
Search tree property
▷ all keys in left subtree smaller than node’s key ▷ all keys in right subtree larger than node’s key
Result: easy to find any given key
2 9 5 20 15 10 7 30 17
In-order: 2, 5, 7, 9, 10, 15, 17, 20, 30 Pre-order: Post-order:
Binary Search Trees are fast if they’re shallow. Know any shallow trees?
▷ perfectly complete ▷ almost complete (except the last level, like a heap) ▷ anything else?
Binary Search Trees are fast if they’re shallow. Know any shallow trees?
▷ perfectly complete ▷ almost complete (except the last level, like a heap) ▷ anything else?
What matters here? Siblings should have about the same height.
x 5 7
balance(x) = height(x.left) − height(x.right) height(NULL) = −1. If for all nodes x,
▷ balance(x) = 0 then perfectly balanced. ▷ |balance(x)| is small then balanced enough. ▷ −1 ≤ balance(x) ≤ 1 then tree height ≤ c lg n where c < 2.
2 8 5 20 17 9 7 14 12 25 21 4 18
Binary tree property
▷ each node has ≤ 2 children
Search tree property
▷ all keys in left subtree smaller than node’s key ▷ all keys in right subtree larger than node’s key
Balance property
▷ For all nodes x, −1 ≤ balance(x) ≤ 1
Result: height is Θ(log n).
2 8 4 20 17 9 7 25 18
17 8 4 25 20 9 7 18 2 3 2 1 2 1 9 3 key height children
Suppose we start with a balanced search tree (an AVL tree).
17 8 4 25 20 9 7 18 2 3 2 1 2 1
insert 5
17 8 4 25 20 9 7 18 2 4 3 2 1 2 1 5
It’s no longer an AVL tree. What can we do?
Suppose we start with a balanced search tree (an AVL tree).
17 8 4 25 20 9 7 18 2 3 2 1 2 1
insert 5
17 8 4 25 20 9 7 18 2 4 3 2 1 2 1 5
It’s no longer an AVL tree. What can we do? ROTATE!
A B x y z
A B x y z
A B x y z
A B x y z
B A x y z
▷ O(1) ▷ O(lg n) ▷ O(n) ▷ O(n lg n) ▷ O(n2) ▷ none of the above
17 8 4 25 20 9 7 18 2 4 3 2 1 2 1 5 17 7 4 25 20 9 5 18 2 3 2 1 2 1 8
rotateRight is shown. There’s also a symmetric rotateLeft.
A z B y h + 2 h + 1 h h − 1 h − 1 x B A y h + 1 h h h − 1 x z h − 1 insert occurred here
After rotation, subtree’s height is the same as before insert. So heights of ancestors don’t change.
Start with
17 7 4 25 20 9 5 18 2 3 2 1 2 1 8
insert 6
17 7 4 25 20 9 5 18 2 4 3 2 1 2 1 8 6
A single rotation won’t fix this.
Start with
17 7 4 25 20 9 5 18 2 3 2 1 2 1 8
insert 6
17 7 4 25 20 9 5 18 2 4 3 2 1 2 1 8 6
A single rotation won’t fix this. DOUBLE ROTATE!
17 5 4 25 20 9 18 2 4 3 2 2 1 7 1 8 6 17 7 4 25 20 9 5 18 2 4 3 2 1 2 1 8 6 17 7 5 25 20 9 18 4 3 2 1 1 2 1 8 2 6 rotateRight rotateLeft
doubleRotateLeft is shown. There’s also a symmetric doubleRotateRight.
insert occurred here or here A z B w h + 1 h h − 1 h − 1 h x C y C w A z h + 2 h + 1 h − 1 h − 1 h y B x h − 1 h − 1
Either x or y increased to height h − 1 after insert. After rotation, subtree’s height is the same as before insert. So height of ancestors doesn’t change.
Case LL: rotateRight Case RR: rotateLeft Case LR: doubleRotateRight Case RL: doubleRotateLeft The case names are the first two steps on the path from the unbalanced ancestor to the new leaf.
Insert(3)
12 9 5 20 15 10 30 2 3 1 2 1 17
12 9 5 20 15 10 30 2 3 2 1 2 1 17 3
Insert(33)
12 9 5 20 15 10 30 2 3 2 1 2 1 17 3
12 9 5 20 15 10 30 2 ? 2 1 3 2 1 17 3 33 12 9 5 20 10 30 2 3 2 1 2 1 1 3 33 17 15
x y z a b y x z a A B B A
void rotateLeft(Node *&a) { Node* b = a->right; a->right = b->left; b->left = a; updateHeight(a); updateHeight(b); a = b; }
Insert(18)
12 9 5 20 15 10 30 2 3 2 1 2 1 17 3
12 9 5 20 15 10 30 2 ? 2 1 3 2 17 1 3 18 12 9 5 20 10 30 2 3 2 1 2 1 1 3 15 12 9 5 20 15 10 2 ? 2 1 3 2 1 3 30 18 17 17 18 rotateRight rotateLeft
A z B w x C y C w A z y B x C w A z y x B a a a
void doubleRotateLeft(Node *&a) { rotateRight(a->right); rotateLeft(a); }
the problem to deleting a node with 0 or 1 child.)
fixing heights).
6 3 2 10 8 5 4 7 1 4 2 1 3 1 2 12 11 9 13 6 5
Observations
▷ Binary search trees that allow only slight imbalance. ▷ Worst-case O(log n) time for find, insert, and delete. ▷ Elements (even siblings) may be scattered in memory.
Realities
▷ For large data sets, disk accesses dominate runtime.
Could we have perfect balance if we relax binary tree restriction?