Fundamental Algithms Chapter 4: AVL Trees Jan Křetínský Winter 2016/17 Chapter 4: AVL Trees, Winter 2016/17 1
Part I AVL Trees (Adelson-Velsky and Landis, 1962) Chapter 4: AVL Trees, Winter 2016/17 2
Binary Search Trees Summary Compleity of Searching: wst-case compleity depends on height of the search trees O(log n) f balanced trees Inserting and Deleting: insertion and deletion might change balance of trees question: how epensie is re-balancing? Test: Inserting/Deleting into a (fully) balanced tree strict balancing (unifm depth f all leaes) too strict Chapter 4: AVL Trees, Winter 2016/17 3
AVL-Trees Definition AVL-trees are binary search trees that fulfill the following balance condition. F eery node height(left sub-tree()) height(right sub-tree()) 1. Lemma An AVL-tree of height h contains at least F h+2 1 and at most 2 internal nodes, where F n is the n-th Fibonacci number (F 0 = 0, F 1 = 1), and the height is the maimal number of edges from the root to an (empty) dummy leaf. Chapter 4: AVL Trees, Winter 2016/17 4
AVL trees Proof. The upper bound is clear, as a binary tree of height h can only contain h 1 2 j = 2 internal nodes. j=0 Chapter 4: AVL Trees, Winter 2016/17 5
AVL trees Proof (cont.) Induction (base cases): 1. an AVL-tree of height h = 1 contains at least one internal node, 1 F 3 1 = 2 1 = 1. 2. an AVL tree of height h = 2 contains at least two internal nodes, 2 F 4 1 = 3 1 = 2 Chapter 4: AVL Trees, Winter 2016/17 6
Induction step: An AVL-tree of height h 2 of minimal size has a root with sub-trees of height and h 2, respectiely. Both sub-trees hae minimal node number. h 2 Let g h := 1 + minimal size of AVL-tree of height h. Then g 1 = 2 = F 3 g 2 = 3 = F 4 g = 1 + g h 1 1 + g h 2 1, hence g h = g h 1 + g h 2 = F h+2
AVL-Tress An AVL-tree of height h contains at least F h+2 1 internal nodes. Since ( n + 1 F h+2 = Ω 1 + ) h 5, 2 we get ( n Ω 1 + ) h 5, 2 and, hence, h = O(log n). Chapter 4: AVL Trees, Winter 2016/17 8
AVL-trees We need to maintain the balance condition through rotations. F this we ste in eery internal tree-node the balance of the node. Let denote a tree node with left child c l and right child c r. balance[] := height(t cl ) height(t cr ), where T cl and T cr, are the sub-trees rooted at c l and c r, respectiely. Chapter 4: AVL Trees, Winter 2016/17 9
Rotations The properties will be maintained through rotations: z LeftRotate() z A RightRotate(z) C B C A B Chapter 4: AVL Trees, Winter 2016/17 10
Double Rotations z y D A B C LeftRotate(y) RightRotate() z y y z D DoubleRightRotate() A B C A B C D
AVL-trees: Insert Insert like in a binary search tree. Let w denote the parent of the newly inserted node. One of the following cases holds: w w w w a a bal(w) = 1 bal(w) = 0 bal(w) = 0 bal(w) = 1 If bal[w] 0, T w has changed height; the balance-constraint may be iolated at ancests of w. Call AVL-fi-up-insert(parent[w]) to reste the balance-condition. Chapter 4: AVL Trees, Winter 2016/17 12
AVL-trees: Insert Inariant at the beginning of AVL-fi-up-insert(): 1. The balance constraints hold at all descendants of. 2. A node has been inserted into T c, where c is either the right left child of. 3. T c has increased its height by one (otw. we would already hae abted the fi-up procedure). 4. The balance at node c fulfills balance[c] { 1, 1}. This holds because if the balance of c is 0, then T c did not change its height, and the whole procedure would hae been abted in the preious step. Chapter 4: AVL Trees, Winter 2016/17 13
AVL-trees: Insert Algithm 1 AVL-fi-up-insert() 1: if balance[] { 2, 2} then DoRotationInsert(); 2: if balance[] {0} return; 3: if parent[] = null return; 4: compute balance of parent[]; 5: AVL-fi-up-insert(parent[]); We will show that the aboe procedure is crect, and that it will do at most one rotation. Chapter 4: AVL Trees, Winter 2016/17 14
AVL-trees: Insert Algithm 2 DoRotationInsert() 1: if balance[] = 2 then // insert in right sub-tree 2: if balance[right[]] = 1 then 3: LeftRotate(); 4: else 5: DoubleLeftRotate(); 6: else // insert in left sub-tree 7: if balance[left[]] = 1 then 8: RightRotate(); 9: else 10: DoubleRightRotate(); Chapter 4: AVL Trees, Winter 2016/17 15
AVL-trees: Insert It is clear that the inariants f the fi-up routine hold as long as no rotations hae been done. We hae to show that after doing one rotation all balance constraints are fulfilled. We show that after doing a rotation at : fulfills balance condition. All children of still fulfill the balance condition. The height of T is the same as befe the insert-operation took place. We only look at the case where the insert happened into the right sub-tree of. The other case is symmetric. Chapter 4: AVL Trees, Winter 2016/17 16
AVL-trees: Insert We hae the following situation: h + 1 The right sub-tree of has increased its height which results in a balance of 2 at. Befe the insertion the height of T was h + 1. Chapter 4: AVL Trees, Winter 2016/17 17
Case 1: balance[right[]] = 1 We do a left rotation at LeftRotate() h h Now, the subtree has height h + 1 as befe the insertion. Hence, we do not need to continue. Chapter 4: AVL Trees, Winter 2016/17 18
Case 2: balance[right[]] = 1 y RightRotate() y h 2 h 2 h 2 h 2 DoubleLeftRotate() y LeftRotate() Height is h + 1, as befe the insert. h 2 h 2
AVL-trees: Delete Delete like in a binary search tree. Let denote the parent of the node that has been spliced out. The balance-constraint may be iolated at, at ancests of, as a sub-tree of a child of has reduced its height. Initially, the node c the new root in the sub-tree that has changed is either a dummy leaf a node with two dummy leafs as children. c Case 1 Case 2 In both cases bal[c] = 0. Call AVL-fi-up-delete() to reste the balance-condition. Chapter 4: AVL Trees, Winter 2016/17 20
AVL-trees: Delete Inariant at the beginning AVL-fi-up-delete(): 1. The balance constraints holds at all descendants of. 2. A node has been deleted from T c, where c is either the right left child of. 3. T c has decreased its height by one. 4. The balance at the node c fulfills balance[c] = 0. This holds because if the balance of c is in { 1, 1}, then T c did not change its height, and the whole procedure would hae been abted in the preious step. Chapter 4: AVL Trees, Winter 2016/17 21
AVL-trees: Delete Algithm 3 AVL-fi-up-delete() 1: if balance[] { 2, 2} then DoRotationDelete(); 2: if balance[] { 1, 1} return; 3: if parent[] = null return; 4: compute balance of parent[]; 5: AVL-fi-up-delete(parent[]); We will show that the aboe procedure is crect. Howeer, f the case of a delete there may be a logarithmic number of rotations. Chapter 4: AVL Trees, Winter 2016/17 22
AVL-trees: Delete Algithm 4 DoRotationDelete() 1: if balance[] = 2 then // deletion in left sub-tree 2: if balance[right[]] {0, 1} then 3: LeftRotate(); 4: else 5: DoubleLeftRotate(); 6: else // deletion in right sub-tree 7: if balance[left[]] = {0, 1} then 8: RightRotate(); 9: else 10: DoubleRightRotate(); Chapter 4: AVL Trees, Winter 2016/17 23
AVL-trees: Delete It is clear that the inariants f the fi-up routine hold as long as no rotations hae been done. We show that after doing a rotation at : fulfills the balance condition. All children of still fulfill the balance condition. If now balance[] { 1, 1} we can stop as the height of T is the same as befe the deletion. We only look at the case where the deleted node was in the right sub-tree of. The other case is symmetric. Chapter 4: AVL Trees, Winter 2016/17 24
AVL-trees: Delete We hae the following situation: h + 1 h The right sub-tree of has decreased its height which results in a balance of 2 at. Befe the deletion the height of T was h + 2. Chapter 4: AVL Trees, Winter 2016/17 25
Case 1: balance[left[]] {0, 1} RightRotate() h h h h If the middle subtree has height h the whole tree has height h + 2 as befe the deletion. The iteration stops as the balance at the root is non-zero. If the middle subtree has height the whole tree has decreased its height from h + 2 to h + 1. We do continue the fi-up procedure as the balance at the root is zero.
Case 2: balance[left[]] = 1 y y LeftRotate() h 2 h 2 h 2 h 2 y RightRotate() Sub-tree has height h + 1, i.e., it has shrunk. The balance at y is zero. We continue the iteration. DoubleRightRotate() h 2 h 2