@@ -10,93 +10,17 @@ renamed according to new structure
10
10
\\Note{ modified from BST - best check actual running BST Real code for
11
11
search and use that XXX still needs unification with BST
12
12
13
- Terminology (might change???)
14
- For BST we confound t.key and t->key, eg, we have c <- c.left. Its not
15
- too bad with BST code, but here the code gets more complex, with
16
- multiple levels of the tree involved using c.left.left is a bit too
17
- dodgy(?). So we use:
18
-
19
- root(t) = (*t)
20
- left(t) = *(t->left) (or Empty) ?????
21
- right() similarly
22
- root(t).key, root(t).height, etc
23
- left(t).height, etc ???
24
- XXX maybe use height(t), key(t), left(t), right(t)
13
+ Terminology (changed, might change again but this looks OK I reckon)
14
+ XXX should change BST (et al?) so it is consistent
15
+ We brush over the fact that pointers are used and use record notation
16
+ "." where C "->" would be used (implicit dereference of pointer).
17
+ t <- t.left etc is the most dubious looking code if we think of records
18
+ and not pointers.
19
+ Basically t = Empty or, otherwise, t.key, t.left and t.right exist (we
20
+ don't explicitly use t.height in the code but could). Creating a new
21
+ singleton tree is done in a single step.
25
22
\\Note}
26
23
27
- \\Overview{ A binary tree is either is either empty (Empty) or else it
28
- it has a root node and two subtrees (which are binary trees).
29
- The root node t has a key, t.key. Ordinarily it would also
30
- hold other data (t.data), which the user would like to find by
31
- searching for the key. Since this attribute has no impact on
32
- how insertion and search take place, we disregard it here.
33
- Note that a newly inserted node will always appear as a leaf
34
- in the tree. The BST invariant is always maintained: for each
35
- subtree t, with root key t.key, the left subtree, t.left,
36
- contains no node with key greater than k, and the right subtree,
37
- t.right, contains no node with key smaller than k.
38
- XXX AVL trees balanced, shorten above
39
- Need to have these rotation explanations here as we can't format
40
- explanations properly it seems:
41
-
42
- ## The left-left case
43
-
44
- If the new key was added to the left child of the left child (the
45
- left-left case) and the resulting tree is too unbalanced, the balance can be
46
- restored with a "Right rotation" operation, as explained in the diagram
47
- below. The 6 and 4 nodes and the edge between them rotate clockwise, and
48
- the 5 node changes parents from 4 to 6. This reduces the distance from
49
- the root to the 1 (where the new node was added), restoring the balance
50
- (the distance to the node rooted at 7 is increased but this does not
51
- cause the AVL tree balance condition to be violated). Right rotation is
52
- done by calling rightRotate(t6), where t6 is the tree rooted at 6.
53
-
54
- '''
55
- 6 2
56
- / \\ Right Rotation / \\
57
- 2 7 - - - - - - - > 1 6
58
- / \\ < - - - - - - - / \\
59
- 1 4 Left Rotation 4 7
60
- '''
61
-
62
- ## The right-right case
63
-
64
- The right-right case is the exact opposite. If the tree on the right in
65
- the diagram above is too unbalanced due to insertion into the subtree
66
- rooted at 7, we can call rightRotate(t2) to lift that subtree and lower
67
- the 1 subtree.
68
-
69
- ## The left-right case (double rotation)
70
-
71
- If the new key was added to the right child of the left child (the
72
- left-right case) and the resulting tree is too unbalanced, the balance can be
73
- restored with a left rotation at node 2 followed by a right rotation at
74
- node 6.
75
- '''
76
- 6 Rotate 6 Rotate 4
77
- / \\ left at 2 / \\ right at 6 / \\
78
- 2 7 - - - - - > 4 7 - - - - - > 2 6
79
- / \\ / \\ / \\ / \\
80
- 1 4 2 5 1 3 5 7
81
- / \\ / \\
82
- 3 5 1 3
83
- '''
84
- Nodes in the subtree rooted at 4 (where the extra element was added,
85
- making the tree unbalanced) are moved closer to the root.
86
- Trees rooted at 1, 3, 5 and 7 are not affected, except the distances from
87
- the root of 3, 5 and 7 are changed by one, affecting the overall balance.
88
-
89
- ## right-left case (double rotation):
90
-
91
- If the new key was added to the left child of the right child (the
92
- right-left case) and the resulting tree is too unbalanced, it is a mirror
93
- image of the left-right case:
94
-
95
- XXX edit diagram above (tree on left won't be consistent with previous
96
- examples but thats OK I think)
97
-
98
- \\Overview}
99
-
100
24
\\Note{ For both insertion and search, the animation should be as
101
25
consistent
102
26
as possible with BST
@@ -124,14 +48,14 @@ AVLT_Insert(t, k) // returns t with key k inserted \\B AVLT_Insert(t, k)
124
48
This is the base case of the recursion.
125
49
\\Expl}
126
50
\\In}
127
- if k < root(t) .key \\B if k < root(t).key
51
+ if k < t .key \\B if k < root(t).key
128
52
\\Expl{ The key in the root determines if we insert into the left or
129
53
right subtree.
130
54
\\Expl}
131
55
\\In{
132
56
insert k into the left subtree of t \\Ref insertLeft
133
57
\\In}
134
- else if k > root(t) .key \\B else if k > root(t).key
58
+ else if k > t .key \\B else if k > root(t).key
135
59
\\Note{ XXX allow duplicate keys or not???
136
60
Should be possible, but have to carefully review code to make sure its
137
61
correct. What does BST code do?
@@ -169,14 +93,10 @@ recursive call plus we need a chunk at this level of recursion just
169
93
before the call so we can step back to it
170
94
\\Note}
171
95
// *recursively* call insert with the left subtree \\B prepare for the left recursive call
172
- AVLT_Insert(left(t) , k) \\B left(t) <- AVLT_Insert(left(t), k)
96
+ t.left <- AVLT_Insert(t.left , k) \\B left(t) <- AVLT_Insert(left(t), k)
173
97
\\Expl{
174
- The left subtree is replaced by the result of this recursive call
98
+ The (possibly empty) left subtree is replaced by the result of this recursive call.
175
99
\\Expl}
176
- \\Note{
177
- XXX should this be left(t) <- AVLT_Insert(left(t), k) or is the
178
- explanation enough? (same for right)
179
- \\Note}
180
100
\\Code}
181
101
182
102
@@ -188,16 +108,16 @@ recursive call plus we need a chunk at this level of recursion just
188
108
before the call so we can step back to it
189
109
\\Note}
190
110
// *recursively* call insert with the right subtree \\B prepare for the right recursive call
191
- AVLT_Insert(right(t) , k) \\B right(t) <- AVLT_Insert(right(t), k)
111
+ t.right <- AVLT_Insert(t.right , k) \\B right(t) <- AVLT_Insert(right(t), k)
192
112
\\Expl{
193
- The right subtree is replaced by the result of this recursive call
113
+ The (possibly empty) right subtree is replaced by the result of this recursive call.
194
114
\\Expl}
195
115
\\Code}
196
116
197
117
\\Code{
198
118
rotateIfNeeded
199
119
switch balanceCase(t) of \\B switch balanceCase of
200
- \\Expl{ If the "balance" of t (left(t). height - right(t) .height) is between -1
120
+ \\Expl{ If the "balance" of t (t.left. height - t.right .height) is between -1
201
121
and 1, inclusive, we just
202
122
return t. Otherwise we must determine which sub-sub-tree the new element was
203
123
inserted into and use "rotation" operations to raise up that subtree and
@@ -216,7 +136,7 @@ case Balanced:// sufficiently balanced \\B case Balanced
216
136
case Left-Left:// Left-Left insertion, unbalanced \\B perform right rotation to re-balance t
217
137
\\Expl{
218
138
Key k was inserted into the left-left subtree and made t unbalanced
219
- (balance > 1 and k < left(t) .key).
139
+ (balance > 1 and k < t.left .key).
220
140
We must re-balance the tree with a "right rotation" that lifts up this
221
141
subtree. See Background (click at the top of the right panel)
222
142
for diagrams etc explaining rotations.
@@ -227,7 +147,7 @@ case Left-Left:// Left-Left insertion, unbalanced \\B perform right rotation to
227
147
case Right-Right:// Right-Right insertion, unbalanced \\B perform left rotation to re-balance t
228
148
\\Expl{
229
149
Key k was inserted into the right-right subtree and made t unbalanced
230
- (balance < -1 and k > right(t) .key).
150
+ (balance < -1 and k > t.right .key).
231
151
We must re-balance the tree with a "left rotation" that lifts up this
232
152
subtree. See Background (click at the top of the right panel)
233
153
for diagrams etc explaining rotations.
@@ -238,38 +158,50 @@ case Right-Right:// Right-Right insertion, unbalanced \\B perform left rotation
238
158
case Left-Right:// Left-Right insertion, unbalanced \\B perform left rotation on the left subtree
239
159
\\Expl{
240
160
Key k was inserted into the left-right subtree and made t unbalanced
241
- (balance > 1 && k > left(t) .key).
242
- Balance can be restored by performing a "left rotation" on left(t) (this
161
+ (balance > 1 && k > t.left .key).
162
+ Balance can be restored by performing a "left rotation" on t.left (this
243
163
lifts up the subtree) followed by a right rotation of t (in case the first
244
164
rotation made the left-left subtree too deep).
245
165
See Background (click at the top of the right panel)
246
166
for diagrams etc explaining rotations.
247
167
\\Expl}
248
168
\\In{
249
- perform leftRotate(left(t)) ; // raise Left-Right subtree \\B left(t) <- leftRotate(left(t));
169
+ t.left <- leftRotate(t.left) ; // raise Left-Right -Right subtree \\B left(t) <- leftRotate(left(t));
250
170
\\Expl{
251
- The result returned is the new left(t). This lowers the Left-Left
252
- subtree.
171
+ This also raises the root of the Left-Right subtree.
172
+ The Left-Right-Left subtree remains at the same level but is now the
173
+ Left-Left-Right subtree (it is raised in the next step).
253
174
\\Expl}
254
175
return rightRotate(t) // raise Left-Left subtree to balance \\B return rightRotate(t) after leftRotate
176
+ \\Expl{
177
+ This raises what was previously the Left-Right-Left subtree, so the
178
+ whole of the previous Left-Right subtree is now higher (and the
179
+ Right subtree is lower).
180
+ \\Expl}
255
181
\\In}
256
182
case Right-Left:// Right-Left insertion, unbalanced \\B perform right rotation on the right subtree
257
183
\\Expl{
258
184
Key k was inserted into the right-left subtree and made t unbalanced
259
- (balance < -1 && k < right(t) .key).
260
- Balance can be restored by performing a "right rotation" on right(t) (this
185
+ (balance < -1 && k < t.right .key).
186
+ Balance can be restored by performing a "right rotation" on t.right (this
261
187
lifts up the subtree) followed by a left rotation of t (in case the first
262
188
rotation made the right-right subtree too deep).
263
189
See Background (click at the top of the right panel)
264
190
for diagrams etc explaining rotations.
265
191
\\Expl}
266
192
\\In{
267
- perform rightRotate(right(t)) ; // raise Right-Left subtree \\B right(t) <- rightRotate(right(t));
193
+ t.right <- rightRotate(t.right) ; // raise Right-Left -Left subtree \\B right(t) <- rightRotate(right(t));
268
194
\\Expl{
269
- The result returned is the new right(t). This lowers the Right-Right
270
- subtree.
195
+ This also raises the root of the Right-Left subtree.
196
+ The Right-Left-Right subtree remains at the same level but is now the
197
+ Right-Right-Left subtree (it is raised in the next step).
271
198
\\Expl}
272
199
return leftRotate(t) // raise Right-Right subtree to balance \\B return leftRotate(t) after rightRotate
200
+ \\Expl{
201
+ This raises what was previously the Right-Left-Right subtree, so the
202
+ whole of the previous Right-Left subtree is now higher (and the
203
+ Left subtree is lower).
204
+ \\Expl}
273
205
\\In}
274
206
// ==== rotation functions ====
275
207
leftRotate(t2) // raises Right-Right + lowers Left-Left subtrees \\B leftRotate(t2)
@@ -280,8 +212,8 @@ See Background (click at the top of the right panel)
280
212
for diagrams etc explaining rotations.
281
213
\\Expl}
282
214
\\In{
283
- t6 <- right(t2) \\B t6 = right(t2)
284
- t4 <- left(t6) // may be Empty \\B t4 = left(t6)
215
+ t6 <- t2.right \\B t6 = right(t2)
216
+ t4 <- t6.left // may be Empty \\B t4 = left(t6)
285
217
t6.left <- t2 \\B t6.left = t2
286
218
t2.right <- t4 // may be Empty \\B t2.right = t4
287
219
recompute heights of t2 and t6 \\B recompute heights of t2 and t6
@@ -298,8 +230,8 @@ See Background (click at the top of the right panel)
298
230
for diagrams etc explaining rotations.
299
231
\\Expl}
300
232
\\In{
301
- t2 <- left(t6) \\B t2 = left(t6)
302
- t4 <- right(t2) // may be Empty \\B t4 = right(t2)
233
+ t2 <- t6.left \\B t2 = left(t6)
234
+ t4 <- t2.right // may be Empty \\B t4 = right(t2)
303
235
t2.right <- t6 \\B t2.right = t6
304
236
t6.left <- t4 // may be Empty \\B t6.left = t4
305
237
\\Note{ Animation here should be as smooth an intuitive as possible.
0 commit comments