|
1 | 1 | # AVL Trees
|
2 | 2 |
|
3 |
| -An AVL tree is **self-balancing** binary search tree. |
4 |
| - |
5 |
| -Because the AVL tree is always balanced, search will be *O(log n)*, |
6 |
| -no matter what the order of the input data. |
7 |
| - |
8 |
| -### Binary Search Trees |
9 |
| - |
10 |
| -A **binary tree** is either is either empty (`Empty`) or else it |
11 |
| - it has a root node and two subtrees (which are binary trees). |
12 |
| - The root node `t` has a key, `t.key`. Ordinarily it would also |
13 |
| - hold other data (`t.data`), which the user would like to find by |
14 |
| - searching for the key. Since this attribute has no impact on |
15 |
| - how insertion and search take place, we disregard it here. |
16 |
| - Note that a newly inserted node will always appear as a leaf |
17 |
| - in the tree. |
18 |
| - |
19 |
| -In a **binary search tree (BST)** the BST invariant is always maintained:\ |
20 |
| -for each |
21 |
| - subtree t, with root key t.key, the left subtree, t.left, |
22 |
| - contains no node with key greater than k, and the right subtree, |
23 |
| - t.right, contains no node with key smaller than k. |
24 |
| - |
25 |
| -### AVL tree balancing |
26 |
| - |
27 |
| -The AVL tree preserves the balance of the tree by (1) checking after every insertion to detect |
28 |
| -when the tree has become unbalanced |
29 |
| -and (2) performing one or more rotation operations to restore balance when necessary. |
30 |
| -Unbalanced is defined as a difference of more than `1` between the heights of the left and right subtrees. |
31 |
| - |
32 |
| -(Here **MAYBE insert small pictures, thumbnails?** to show -- unbalanced at gp of new node, |
33 |
| -and also balanced at gp but unblanaced at ggp.) |
34 |
| - |
35 |
| -A temporarily unbalanced AVL tree takes on one of two configurations, *zig-zag* or *zig-zig*. The |
36 |
| -sequence of rotations depends on the configuration around the node where the imbalance is detected. |
37 |
| - |
38 |
| -### Zig-zig case |
39 |
| - |
40 |
| -The *zig-zig* configuration has two mirror-image cases: the child and grandchild nodes or subtrees of the unbalanced node are |
41 |
| -either (1) both left subtrees or (2) both right subtrees. |
42 |
| - |
43 |
| - |
44 |
| -## The left-left case |
45 |
| - |
46 |
| -If the new key was added to the left child of the left child (the |
47 |
| -*left-left* case), the balance can be |
48 |
| -restored with a single _**Right Rotation**_ operation. |
| 3 | +An AVL tree is a kind of **binary search tree** that is |
| 4 | +**self-balancing**. |
| 5 | + |
| 6 | +Unlike a basic binary search tree, which can exhibit *O(n)* worst case |
| 7 | +behavior for both search and insert, an AVL tree is always balanced, so |
| 8 | +the worst case *O(log n)*. The way balanced is maintained is quite |
| 9 | +complicated; we suggest experimenting with the examples at the end of |
| 10 | +this background. |
| 11 | + |
| 12 | +A **binary search tree (BST)** is either empty or else it is a root |
| 13 | +node containing a key and two subtrees, which are binary search trees. |
| 14 | +Binary trees are ordered, so keys in the left subtree are smaller (or |
| 15 | +equal to) the key in the root and keys in the right subtree are greater |
| 16 | +(or equal to). Normally there is additional data in each node as well |
| 17 | +as the key, disregarded here. For an **AVL tree**, nodes also contain |
| 18 | +the *height* of the tree; this is used in the insertion algorithm to |
| 19 | +ensure the tree is balanced. The two children of an AVL tree node have |
| 20 | +*a height difference of at most one*. The height is ignored for search |
| 21 | +and AVL tree search is identical to BST search. |
| 22 | + |
| 23 | +## Insertion |
| 24 | + |
| 25 | +BST insertion traverses down the tree from the root (going left or |
| 26 | +right at each stage, depending on the comparison between the key in |
| 27 | +the node and the key to be inserted) then adds new leaf containing the |
| 28 | +inserted key. AVL tree insertion does the same, but additionally, the |
| 29 | +height information is updated and the tree may be adjusted to restore the |
| 30 | +balance. The coding here is recursive, with each recursive insert call |
| 31 | +going one step further down the tree. After each recursive call returns |
| 32 | +(implicitly traversing back up the tree to the root) the height adjustment |
| 33 | +and re-balancing is performed. The collapsed pseudocode is simply BST |
| 34 | +insertion code containing recursive calls, with code for height update |
| 35 | +and re-balancing added at the end. The new height is simply the maximum |
| 36 | +height of the two subtrees plus 1. |
| 37 | + |
| 38 | +### Tree re-balancing |
| 39 | + |
| 40 | +If the difference between the heights of the left and right subtrees is |
| 41 | +more than one, the tree is considered unbalanced and must be rearranged |
| 42 | +so that it is balanced. This is done by **local** operations, called |
| 43 | +**rotations**, that simply re-assign several pointers in the vicinity |
| 44 | +of the node. A rotation will raise up one subtree and lower another; |
| 45 | +the AVL insertion algorithm chooses what rotations to perform so as |
| 46 | +to ensure the tree is balanced after the insertion operation has been |
| 47 | +completed (assuming it was balanced to begin with). |
| 48 | + |
| 49 | +An AVL tree node can only become unbalanced if insertion into one of the |
| 50 | +"grandchildren" (sub-sub-trees) increased the height of the tree. There |
| 51 | +are four grandchildren (called "left-left", "left-right", "right-left" |
| 52 | +and "right-right"), which must be handled separately. For the left-left |
| 53 | +and right-right cases a single rotation operation will restore balance. |
| 54 | +The other two cases each require two rotation operations. |
| 55 | + |
| 56 | +#### Single rotations |
| 57 | + |
| 58 | +A single rotation transforms the tree as shown in the diagram below, |
| 59 | +where t1, t4 and t7 are subtrees that may be of any size (in the "More" |
| 60 | +tab there is a W3Schools link that has an animation of these |
| 61 | +rotations). |
| 62 | +``` |
| 63 | + / / |
| 64 | + t6 t2 |
| 65 | + / \ Right Rotation / \ |
| 66 | + t2 t7 - - - - - - - > t1 t6 |
| 67 | + / \ < - - - - - - - / \ |
| 68 | + t1 t4 Left Rotation t4 t7 |
| 69 | +``` |
49 | 70 |
|
50 |
| -Note that the imbalance may be located further up the tree than the immediate grandparent of the newly inserted node: |
| 71 | +Going from left to right (a **right rotation** of t6), subtree t1 is |
| 72 | +raised and t7 is lowered, but the ordering is preserved. You can think of |
| 73 | +t6, t2 and the edge between them being rotated clockwise, so t2 becomes |
| 74 | +the parent and t6 becomes the right child. Additionally, the parent of t4 |
| 75 | +changes and the root of the tree changes (so the pointer from its parent |
| 76 | +changes). If t6 was unbalanced due to an insertion into t1 (the left-left |
| 77 | +case), this restores the balance. Similarly, the inverse operation, going |
| 78 | +from right to left (a **left rotation** of t2), restores the balance if |
| 79 | +unbalance was caused by insertion into t7 (the right-right case). The AIA |
| 80 | +pseudocode for rotation uses variables names consistent with this diagram. |
51 | 81 |
|
52 |
| -**Insert very small diagrams showing (a) imbalance of the grandparent-parent and (b) imbalance of the great grandparent** |
53 |
| -*Note that all diagrams should hae nodes in BST order, and where the subtrees are not necessarily single nodes, represent them as subtree-triangles* |
54 |
| -*Have arrow showing which node is not in blanace* |
| 82 | +#### Double rotations |
55 | 83 |
|
| 84 | +If the tree becomes unbalanced due to insertion into t4 (the left-right |
| 85 | +case), balance can be restored by performing a left rotation at t2 |
| 86 | +followed by a right rotation at t6, as shown in the following digram: |
56 | 87 |
|
57 |
| -, as explained in the diagram |
58 |
| -below. The 6 and 4 nodes and the edge between them rotate clockwise, and |
59 |
| -the 5 node changes parents from 4 to 6. This reduces the distance from |
60 |
| -the root to the 1 (where the new node was added), restoring the balance |
61 |
| -(the distance to the node rooted at 7 is increased but this does not |
62 |
| -cause the AVL tree balance condition to be violated). Right rotation is |
63 |
| -done by calling rightRotate(t6), where t6 is the tree rooted at 6. |
| 88 | +``` |
| 89 | + / / / |
| 90 | + t6 Rotate t6 Rotate t4 |
| 91 | + / \ left at t2 / \ right at t6 / \ |
| 92 | + t2 t7 - - - - - > t4 t7 - - - - - > t2 t6 |
| 93 | + / \ / \ / \ / \ |
| 94 | +t1 t4 t2 t5 t1 t3 t5 t7 |
| 95 | + / \ / \ |
| 96 | + t3 t5 t1 t3 |
| 97 | +``` |
64 | 98 |
|
65 |
| -{width=120,height=50} This picture is from Greek for Geeks, and is only a placeholder to show proof of concept inserting diagrams, and to check things like size and cropping. |
66 |
| - |
| 99 | +Note that subtree t4 is broken into three parts but all these parts are |
| 100 | +raised whereas t7 is lowered (and the order is preserved). The right-left |
| 101 | +case is the mirror image and balance can be restored with a right rotation |
| 102 | +followed by a left rotation (for brevity we omit the details). |
67 | 103 |
|
| 104 | +## Examples |
68 | 105 |
|
| 106 | +The following examples of inputs result in rotation for the last key |
| 107 | +inserted. You can copy/paste these into AIA, use the progress bar to |
| 108 | +get to the point where the last key is inserted and step through the |
| 109 | +execution; expand the pseudocode to show details of the rotations being |
| 110 | +performed. |
69 | 111 |
|
| 112 | +### Left-left cases (right rotations) |
70 | 113 |
|
| 114 | +The following examples show a simplest case (where t4 is empty), a |
| 115 | +case most like the first diagram above, a case where the rotation is |
| 116 | +not at the root and a case where insertion is several levels below the |
| 117 | +rotation point. |
71 | 118 |
|
72 | 119 | ```
|
73 |
| - 6 2 |
74 |
| - / \ Right Rotation / \ |
75 |
| - 2 7 - - - - - - - > 1 6 |
76 |
| - / \ < - - - - - - - / \ |
77 |
| - 1 4 Left Rotation 4 7 |
| 120 | +60,20,10 |
| 121 | +60,20,70,10,40,15 |
| 122 | +60,20,70,10,5 |
| 123 | +60,20,70,10,40,80,30,5,15,12 |
78 | 124 | ```
|
79 | 125 |
|
80 |
| -## The right-right case |
81 |
| - |
82 |
| -The right-right case is the exact opposite. If the tree on the right in |
83 |
| -the diagram above is too unbalanced due to insertion into the subtree |
84 |
| -rooted at 7, we can call rightRotate(t2) to lift that subtree and lower |
85 |
| -the 1 subtree. |
| 126 | +### Right-right cases (left rotations) |
86 | 127 |
|
87 |
| -## The left-right case (double rotation) |
| 128 | +In the following examples the trees are mirror images of the ones above. |
88 | 129 |
|
89 |
| -If the new key was added to the right child of the left child (the |
90 |
| -left-right case) and the resulting tree is too unbalanced, the balance can be |
91 |
| -restored with a left rotation at node 2 followed by a right rotation at |
92 |
| -node 6. |
93 | 130 | ```
|
94 |
| - 6 Rotate 6 Rotate 4 |
95 |
| - / \ left at 2 / \ right at 6 / \ |
96 |
| - 2 7 - - - - - > 4 7 - - - - - > 2 6 |
97 |
| - / \ / \ / \ / \ |
98 |
| - 1 4 2 5 1 3 5 7 |
99 |
| - / \ / \ |
100 |
| - 3 5 1 3 |
| 131 | +20,60,70 |
| 132 | +20,10,60,40,70,65 |
| 133 | +20,10,60,40,35 |
| 134 | +20,10,60,5,40,70,50,65,80,67 |
101 | 135 | ```
|
102 |
| -Nodes in the subtree rooted at 4 (where the extra element was added, |
103 |
| -making the tree unbalanced) are moved closer to the root. |
104 |
| -Trees rooted at 1, 3, 5 and 7 are not affected, except the distances from |
105 |
| -the root of 3, 5 and 7 are changed by one, affecting the overall balance. |
106 | 136 |
|
107 |
| -## right-left case (double rotation): |
| 137 | +### Left-right and right-left cases (double rotations) |
108 | 138 |
|
109 |
| -If the new key was added to the left child of the right child (the |
110 |
| -right-left case) and the resulting tree is too unbalanced, it is a mirror |
111 |
| -image of the left-right case: |
| 139 | +These cases require double rotations. |
112 | 140 |
|
113 | 141 | ```
|
114 |
| - 2 Rotate 2 Rotate 4 |
115 |
| - / \ right at 6 / \ left at 2 / \ |
116 |
| - 1 6 - - - - - > 1 4 - - - - - > 2 6 |
117 |
| - / \ / \ / \ / \ |
118 |
| - 4 7 3 6 1 3 5 7 |
119 |
| - / \ / \ |
120 |
| - 3 5 5 7 |
| 142 | +60,20,40 |
| 143 | +60,20,70,40,10,30 |
| 144 | +20,60,40 |
| 145 | +20,10,60,40,70,30 |
121 | 146 | ```
|
0 commit comments