Professional Documents
Culture Documents
9
The runtime of adding to / searching a
BST is closely related to height. 6 14
height
balanced 4 8 19
7
Some height numbers
• Observation: The shallower the BST, the better.
Average case height is O(log N)
Worst case height is O(N)
Simple cases such as adding (1, 2, 3, ..., N), or the opposite order,
lead to the worst case scenario: height O(N). (as we saw last class)
root
• For binary tree of height h:
max # of leaves: 2h-1 15
max # of nodes: 2h - 1
min # of leaves: 1 8 20
min # of nodes: h
2 14 18 21
Calculating tree height
• Height is max number of nodes in path from root to any leaf.
height(null) = 0
height(a leaf) = ?
height(A) = ? A
basic idea: When nodes are added to / removed from the tree,
if the tree becomes unbalanced, repair the tree until balance is
restored.
• rebalancing operations are relatively efficient (O(1))
• overall tree maintains a balanced O(log N) height, remains fast for
add/remove/search
Balance factor
• balance factor, for a tree node T :
= height of T's right subtree minus height of T's left subtree.
BF(T) = Height(T->right) - Height(T->left)
-2
• (the tree at right shows BF of each node)
0
AVL tree examples
Two binary search trees:
(a) an AVL tree
(b) not an AVL tree (unbalanced nodes are darkened)
Which are valid AVL trees?
• What is the balance factor of each tree node?
14
5 4
9 28
2 7 2 5
6 9 31
4 -1
8
4 20 44
3 -2 3
3
0 15 22
-4
1
11 33
Tracking subtree height
• Many of the AVL tree operations depend on height.
Height can be computed recursively by walking the tree; too slow.
Instead, each node can keep track of its subtree height as a field:
struct tag {
<type> data;
10 data
int height; 4 4 height
struct tag * left; 10
struct tag * right; left/
} TreeNode
3 2 right
5 20
1 2 1 1
2 9 15 30
1
7
AVL add operation
• For all AVL operations, we assume the tree was balanced before the
operation began.
Adding a new node begins the same as with a typical BST, traversing
left and right to find the proper location and attaching the new node.
But adding this new node may unbalance the tree by 1:
add(49); 55 55
29 87 29 87
-3 42 -3 42
49
AVL add cases
• Consider the lowest node k2 that has now become unbalanced.
The new offending node could be in one of the four following
grandchild subtrees, relative to k2:
25 8
rotate right
8 3 25
3 11 11
Right rotation
• right rotation (clockwise): (fixes Case 1 (LL))
left child k1 becomes parent
original parent k2 demoted to right
k1's original right subtree B (if any) is attached to k2 as left subtree
Right rotation example
43
11
11 65
8 43
8 27
3 27 65
3
Right rotation steps
1. Detach left child (11)'s right subtree (27) (don't lose it!)
2. Consider left child (11) be the new parent.
3. Attach old parent (43) as the right child of new parent (11).
4. Attach new parent (11)'s old right subtree (27)
as left subtree of old parent (43).
43 43 11
11 65 11
65
8 43
8 27 8 27
3 27 65
3 3
Right rotation code
TreeNode * rightRotate(TreeNode * oldParent) {
// 1. detach left child's right subtree
TreeNode * orphan = oldParent->left->right;
return newParent;
}
Right rotation code
int height(TreeNode node) {
if (node == null) {
return 0;
}
int left = (node->left == null) ? 0 : (node->left)->height;
int right = (node->right == null) ? 0 : (node->right)->height;
43 43 65
21 65 65
21 43 87
51 87 51 87
21 51 73
73 73
Left rotation code
TreeNode * leftRotate(TreeNode * oldParent) {
// 1. detach right child's left subtree
TreeNode * orphan = oldParent->right->left;
return newParent;
}
Problem cases
• A single right rotation does not fix Case 2 (LR).
43 43 27
11 65 27 65
11 43
8 27 11 31
8 31 65
31 8
Left-right rotation example
• What is the balance factor of k1, k2, k3 before and after rotating?
Right-left double rotation
• right-left double rotation: (fixes Case 3 (RL))
1) right-rotate k1's right child ... reduces Case 3 into Case 4
2) left-rotate k1 to fix Case 4
Right-left rotation steps
1. Right-rotate the overall parent's right child (11).
• This reduces Case 3 (RL) to Case 4 (RR).
2. Right-rotate the overall parent (43).
• This repairs Case 4 to be balanced.
24 24 31
11 55 11 31 24 55
31 68 55 11 31 47 68
47 47 68
AVL add example
• Draw the AVL tree that would result if the following numbers were
added in this order to an initially empty tree:
20, 45, 90, 70, 10, 40, 35, 30, 99, 60, 50, 80
45
20 70
10 35 60 90
30 40 50 80 99
Add implementation
• Perform normal BST add. But as recursive calls return, update each
node's height from new leaf back up to root.
If a node's balance factor becomes +/- 2, rotate to rebalance it.
• How do you know which of the four Cases you are in?
Current node BF < -1 Case 1 (LL) or 2 (LR).
• look at current node's left child BF.
left child BF < 0 Case 1 (fix with R rotation)
left child BF > 0 Case 2 (fix with LR rotations)
Current node BF > 1 Case 3 (RL) or 4 (RR).
• look at current node's right child BF.
right child BF < 0 Case 3 (fix with RL rotations)
right child BF > 0 Case 4 (fix with L rotation)
AVL remove
• Removing from an AVL tree can also unbalance the tree.
Similar cases as with adding: LL, LR, RL, RR
Can be handled with the same remedies: rotate R, LR, RL, L
remove(8);
11 11
8 43 43
27 65 27 65
Efficiency of AVL
• An AVL tree has the same general operations as a BST, with
rebalancing added to the add/remove operations.
add: O(log N) to walk down the tree and add the element;
O(log N) number of nodes' heights to update;
O(1) single node may need to be rotated. O(log N) overall.
search: O(log N).
remove: O(log N) to walk down the tree and remove the element;
O(log N) number of nodes' heights to update;
O(1) single node may need to be rotated. O(log N) overall.