Skip to content

Commit cfd8eb3

Browse files
committed
AVL tree spec mods
1 parent bcd609e commit cfd8eb3

File tree

1 file changed

+109
-95
lines changed

1 file changed

+109
-95
lines changed

src/algorithms/pseudocode/avltree.real

Lines changed: 109 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,65 @@ left(t).height, etc ???
3030
contains no node with key greater than k, and the right subtree,
3131
t.right, contains no node with key smaller than k.
3232
XXX AVL trees balanced, shorten above
33+
Need to have these rotation explanations here as we can't format
34+
explanations properly it seems:
35+
36+
## The left-left case
37+
38+
If the new key was added to the left child of the left child (the
39+
left-left case) and the resulting tree is too unbalanced, the balance can be
40+
restored with a "Right rotation" operation, as explained in the diagram
41+
below. The 6 and 4 nodes and the edge between them rotate clockwise, and
42+
the 5 node changes parents from 4 to 6. This reduces the distance from
43+
the root to the 1 (where the new node was added), restoring the balance
44+
(the distance to the node rooted at 7 is increased but this does not
45+
cause the AVL tree balance condition to be violated). Right rotation is
46+
done by calling rightRotate(t6), where t6 is the tree rooted at 6.
47+
48+
```
49+
6 2
50+
/ \ Right Rotation / \
51+
2 7 - - - - - - - > 1 6
52+
/ \ < - - - - - - - / \
53+
1 4 Left Rotation 4 7
54+
```
55+
56+
## The right-right case
57+
58+
The right-right case is the exact opposite. If the tree on the right in
59+
the diagram above is too unbalanced due to insertion into the subtree
60+
rooted at 7, we can call rightRotate(t2) to lift that subtree and lower
61+
the 1 subtree.
62+
63+
## The left-right case (double rotation)
64+
65+
If the new key was added to the right child of the left child (the
66+
left-right case) and the resulting tree is too unbalanced, the balance can be
67+
restored with a left rotation at node 2 followed by a right rotation at
68+
node 6.
69+
```
70+
6 Rotate 6 Rotate 4
71+
/ \ left at 2 / \ right at 6 / \
72+
2 7 - - - - - > 4 7 - - - - - > 2 6
73+
/ \ / \ / \ / \
74+
1 4 2 5 1 3 5 7
75+
/ \ / \
76+
3 5 1 3
77+
```
78+
Nodes in the subtree rooted at 4 (where the extra element was added,
79+
making the tree unbalanced) are moved closer to the root.
80+
Trees rooted at 1, 3, 5 and 7 are not affected, except the distances from
81+
the root of 3, 5 and 7 are changed by one, affecting the overall balance.
82+
83+
## right-left case (double rotation):
84+
85+
If the new key was added to the left child of the right child (the
86+
right-left case) and the resulting tree is too unbalanced, it is a mirror
87+
image of the left-right case:
88+
89+
XXX edit diagram above (tree on left won't be consistent with previous
90+
examples but thats OK I think)
91+
3392
\Overview}
3493

3594
\Note{ For both insertion and search, the animation should be as
@@ -130,78 +189,62 @@ AVLT_Insert(t, k) // Insert key k in AVL tree t
130189
\Expl{ Rotations are local tree operations that increase the
131190
height/depth of one subtree but decrease that of another, used to
132191
make the tree more balanced.
192+
See Background (click at the top of the right panel)
193+
for diagrams etc explaining rotations.
133194
\Expl}
134195
return t
135196
\In}
136197

137198
\\============================================================================
199+
\Note{ Might be best to expand these inline rather than having extra
200+
functions. Functions are always visible, which is distracting when things
201+
are collapsed and they are relatively short. However, we would end up
202+
with two copies of each, and rather long code if we expand everyting.
203+
The variable names here are linked to the diagrams, which may be easier for
204+
functions but may also be confusing.
205+
\Note}
138206
rightRotate(t6)
139207
\Expl{
140-
Rotate right, as in the following example:
141-
```
142-
6 4
143-
/ \ Right Rotation / \
144-
4 7 - - - - - - - > 2 6
145-
/ \ < - - - - - - - / \
146-
2 5 Left Rotation 5 7
147-
```
148-
Trees rooted at 2, 5, and 7 are not affected, except the distances from
149-
the root of 2 and 7 are changed by one, affecting the overall balance.
208+
See Background (click at the top of the right panel)
209+
for diagrams etc explaining rotations.
150210
\Expl}
151211
\In{
152-
t4 <- left(t6)
153-
t5 <- right(t4)
154-
t4.right <- t6
155-
t6.left <- t5
212+
t2 <- left(t6)
213+
t4 <- right(t2)
214+
t2.right <- t6
215+
t6.left <- t4
156216
\Note{ Animation here should be as smooth an intuitive as possible.
157-
Ideally node 5 shold get detached from 4 but remain in place then
158-
get re-attached to 6. We could possibly move 7 down to the level of 5
159-
at the first step and delay moving 2 up until the end. Best highlight
160-
the edge between 6 and 4. If extra steps are required for animation
217+
Ideally node 4 should get detached from 2 but remain in place then
218+
get re-attached to 6. We could possibly move 7 down to the level of 4
219+
at the first step and delay moving 1 up until the end. Best highlight
220+
the edge between 6 and 2. If extra steps are required for animation
161221
we can stay on the same line of code for more than one step if
162222
needed. Similarly for left rotation.
163223
\Note}
164-
recompute heights of t6 and t4
165-
\Expl{ t6.height <- max(t5.height, t7.height) + 1;
166-
t4.height <- max(t6.height, t2.height) + 1;
224+
recompute heights of t6 and t2
225+
\Expl{ t6.height <- max(t4.height, t7.height) + 1;
226+
t2.height <- max(t6.height, t1.height) + 1;
167227
\Expl}
168228
\Note{ Best not expand this? Should be clear enough and we are a bit
169229
fast and loose with nodes versus pointers here
170230
\Note}
171-
return (pointer to) t4 // new root
231+
return (pointer to) t2 // new root
172232
\In}
173233

174234
\\============================================================================
175-
leftRotate(t4)
235+
leftRotate(t2)
176236
\Expl{
177-
Rotate left, as in the following example (the opposite of right
178-
rotation):
179-
```
180-
6 4
181-
/ \ Right Rotation / \
182-
4 7 - - - - - - - > 2 6
183-
/ \ < - - - - - - - / \
184-
2 5 Left Rotation 5 7
185-
```
186-
Trees rooted at 2, 5, and 7 are not affected, except the distances from
187-
the root of 2 and 7 are changed by one, affecting the overall balance.
237+
See Background (click at the top of the right panel)
238+
for diagrams etc explaining rotations.
188239
\Expl}
189240
\In{
190-
t6 <- right(t4)
191-
t5 <- left(t6)
192-
t6.left <- t4
193-
t4.right <- t5
194-
\Note{ Animation here should be as smooth an intuitive as possible.
195-
Ideally node 5 shold get detached from 4 but remain in place then
196-
get re-attached to 6. We could possibly move 7 down to the level of 5
197-
at the first step and delay moving 2 up until the end. Best highlight
198-
the edge between 6 and 4. If extra steps are required for animation
199-
we can stay on the same line of code for more than one step if
200-
needed. Similarly for left rotation.
201-
\Note}
202-
recompute heights of t4 and t6
203-
\Expl{ t4.height <- max(t2.height, t5.height) + 1;
204-
t6.height <- max(t4.height, t7.height) + 1;
241+
t6 <- right(t2)
242+
t4 <- left(t6)
243+
t6.left <- t2
244+
t2.right <- t4
245+
recompute heights of t2 and t6
246+
\Expl{ t2.height <- max(t1.height, t4.height) + 1;
247+
t6.height <- max(t2.height, t7.height) + 1;
205248
\Expl}
206249
return (pointer to) t6 // new root
207250
\In}
@@ -280,12 +323,14 @@ if balance > 1 && k < left(t).key // left-left case
280323
\Expl}
281324
\In{
282325
// Perform "right rotation" to re-balance t
283-
\Expl{ See explanation in rightRotate()
326+
\Expl{
327+
See Background (click at the top of the right panel)
328+
for diagrams etc explaining rotations.
284329
\Expl}
285330
\Note{
286331
Animation should stop at the comment above then jump to the
287332
rightRotate code then stop at return *after* rightRotate then go
288-
back to the insert call
333+
back to the insert call???; May be better to inline it
289334
\Note}
290335
return rightRotate(t)
291336
\In}
@@ -297,7 +342,9 @@ if balance < -1 && k > right(t).key // right-right case
297342
\Expl}
298343
\In{
299344
// Perform "left rotation" to re-balance t
300-
\Expl{ See explanation in leftRotate()
345+
\Expl{
346+
See Background (click at the top of the right panel)
347+
for diagrams etc explaining rotations.
301348
\Expl}
302349
\Note{
303350
See notes in left-left case
@@ -306,65 +353,33 @@ if balance < -1 && k > right(t).key // right-right case
306353
\In}
307354
if balance > 1 && k > left(t).key // left-right case (double rotation)
308355
\Expl{
309-
Key k was inserted into the left-right subtree and made t unbalanced.
310-
We re-balance the tree using *two* rotations: first a left rotate of
311-
the left subtree, then a right rotate of the tree itself, as in the
312-
following example (best fully understand single rotations first):
313-
```
314-
6 Rotate 6 Rotate 4
315-
/ \ left at 2 / \ right at 6 / \
316-
2 7 - - - - - > 4 7 - - - - - > 2 6
317-
/ \ / \ / \ / \
318-
1 4 2 5 1 3 5 7
319-
/ \ / \
320-
3 5 1 3
321-
```
322-
Nodes in the subtree rooted at 4 (where the extra element was added,
323-
making the tree unbalanced) are moved closer to the root.
324-
Trees rooted at 1, 3, 5 and 7 are not affected, except the distances from
325-
the root of 3, 5 and 7 are changed by one, affecting the overall balance.
356+
See Background (click at the top of the right panel)
357+
for diagrams etc explaining rotations.
326358
\Expl}
327359
\In{
328360
// Perform "left rotation" on the left subtree
329361
\Note{
330362
Animation should stop at the comment above then jump to the
331-
leftRotate code;
363+
leftRotate code???; May be better to inline it
332364
XXX should we play fast and loose with node vs pointer here and use
333365
t.left <- leftRotate(t.left) or have left(t) <- ... ???
334366
\Note}
335367
perform leftRotate(left(t));
336368
\Expl{
337-
The result returned is the new t.left. See explanation of the "if"
338-
above.
369+
The result returned is the new t.left.
339370
\Expl}
340-
// Perform "right rotation" on t
371+
// Return "right rotation" on t
341372
\Note{
342373
Animation should stop at the comment above then jump to the
343374
rightRotate code then stop at return *after* rightRotate then go
344-
back to the insert call
375+
back to the insert call???; May be better to inline it
345376
\Note}
346377
return rightRotate(t)
347378
\In}
348379
if balance < -1 && k < right(t).key // right-left case (double rotation)
349380
\Expl{
350-
Key k was inserted into the right-left subtree and made t unbalanced.
351-
We re-balance the tree using *two* rotations: first a right rotate of
352-
the right subtree, then a left rotate of the tree itself, as in the
353-
following example (best fully understand single rotations first):
354-
XXX FIX THIS - ITS THE left-right case
355-
```
356-
6 Rotate 6 Rotate 4
357-
/ \ left at 2 / \ right at 6 / \
358-
2 7 - - - - - > 4 7 - - - - - > 2 6
359-
/ \ / \ / \ / \
360-
1 4 2 5 1 3 5 7
361-
/ \ / \
362-
3 5 1 3
363-
```
364-
XXX Nodes in the subtree rooted at 4 (where the extra element was added,
365-
making the tree unbalanced) are moved closer to the root.
366-
Trees rooted at 1, 3, 5 and 7 are not affected, except the distances from
367-
the root of 3, 5 and 7 are changed by one, affecting the overall balance.
381+
See Background (click at the top of the right panel)
382+
for diagrams etc explaining rotations.
368383
\Expl}
369384
\In{
370385
// Perform "right rotation" on the right subtree
@@ -373,10 +388,9 @@ the root of 3, 5 and 7 are changed by one, affecting the overall balance.
373388
\Note}
374389
perform rightRotate(right(t));
375390
\Expl{
376-
The result returned is the new t.right. See explanation of the "if"
377-
above.
391+
The result returned is the new t.right.
378392
\Expl}
379-
// Perform "left rotation" on t
393+
// Return "left rotation" on t
380394
return leftRotate(t)
381395
\In}
382396

0 commit comments

Comments
 (0)