Rev 2501 | Rev 2504 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2501 | Rev 2503 | ||
---|---|---|---|
Line 105... | Line 105... | ||
105 | p = p->lft; |
105 | p = p->lft; |
106 | 106 | ||
107 | return p; |
107 | return p; |
108 | } |
108 | } |
109 | 109 | ||
- | 110 | #define REBALANCE_INSERT_XX(DIR1, DIR2) \ |
|
- | 111 | top->DIR1 = par->DIR2; \ |
|
- | 112 | if (top->DIR1 != NULL) \ |
|
- | 113 | top->DIR1->par = top; \ |
|
- | 114 | par->par = top->par; \ |
|
- | 115 | top->par = par; \ |
|
- | 116 | par->DIR2 = top; \ |
|
- | 117 | par->balance = 0; \ |
|
- | 118 | top->balance = 0; \ |
|
- | 119 | *dpc = par; |
|
- | 120 | ||
- | 121 | #define REBALANCE_INSERT_LL() REBALANCE_INSERT_XX(lft, rgt) |
|
- | 122 | #define REBALANCE_INSERT_RR() REBALANCE_INSERT_XX(rgt, lft) |
|
- | 123 | ||
- | 124 | #define REBALANCE_INSERT_XY(DIR1, DIR2, SGN) \ |
|
- | 125 | gpa = par->DIR2; \ |
|
- | 126 | par->DIR2 = gpa->DIR1; \ |
|
- | 127 | if (gpa->DIR1 != NULL) \ |
|
- | 128 | gpa->DIR1->par = par; \ |
|
- | 129 | gpa->DIR1 = par; \ |
|
- | 130 | par->par = gpa; \ |
|
- | 131 | top->DIR1 = gpa->DIR2; \ |
|
- | 132 | if (gpa->DIR2 != NULL) \ |
|
- | 133 | gpa->DIR2->par = top; \ |
|
- | 134 | gpa->DIR2 = top; \ |
|
- | 135 | gpa->par = top->par; \ |
|
- | 136 | top->par = gpa; \ |
|
- | 137 | \ |
|
- | 138 | if (gpa->balance == -1 * SGN) { \ |
|
- | 139 | par->balance = 0; \ |
|
- | 140 | top->balance = 1 * SGN; \ |
|
- | 141 | } else if (gpa->balance == 0) { \ |
|
- | 142 | par->balance = 0; \ |
|
- | 143 | top->balance = 0; \ |
|
- | 144 | } else { \ |
|
- | 145 | par->balance = -1 * SGN; \ |
|
- | 146 | top->balance = 0; \ |
|
- | 147 | } \ |
|
- | 148 | gpa->balance = 0; \ |
|
- | 149 | *dpc = gpa; |
|
- | 150 | ||
- | 151 | #define REBALANCE_INSERT_LR() REBALANCE_INSERT_XY(lft, rgt, 1) |
|
- | 152 | #define REBALANCE_INSERT_RL() REBALANCE_INSERT_XY(rgt, lft, -1) |
|
- | 153 | ||
110 | /** Insert new node into AVL tree. |
154 | /** Insert new node into AVL tree. |
111 | * |
155 | * |
112 | * @param t AVL tree. |
156 | * @param t AVL tree. |
113 | * @param newnode New node to be inserted. |
157 | * @param newnode New node to be inserted. |
114 | */ |
158 | */ |
Line 143... | Line 187... | ||
143 | gpa = par; |
187 | gpa = par; |
144 | dpc = par->key > key ? &par->lft: &par->rgt; |
188 | dpc = par->key > key ? &par->lft: &par->rgt; |
145 | } |
189 | } |
146 | 190 | ||
147 | /* |
191 | /* |
148 | * Initialize new node. |
192 | * Initialize the new node. |
149 | */ |
193 | */ |
150 | newnode->key = key; |
194 | newnode->key = key; |
151 | newnode->lft = NULL; |
195 | newnode->lft = NULL; |
152 | newnode->rgt = NULL; |
196 | newnode->rgt = NULL; |
153 | newnode->par = gpa; |
197 | newnode->par = gpa; |
Line 160... | Line 204... | ||
160 | *dpc = newnode; |
204 | *dpc = newnode; |
161 | return; |
205 | return; |
162 | } |
206 | } |
163 | 207 | ||
164 | /* |
208 | /* |
165 | * Insert new node into previously found leaf place. |
209 | * Insert the new node into the previously found leaf position. |
166 | */ |
210 | */ |
167 | *dpc = newnode; |
211 | *dpc = newnode; |
168 | 212 | ||
169 | /* |
213 | /* |
170 | * If the tree contains one node - end. |
214 | * If the tree contains one node - end. |
Line 207... | Line 251... | ||
207 | par = top->lft; |
251 | par = top->lft; |
208 | if (par->balance == -1) { |
252 | if (par->balance == -1) { |
209 | /* |
253 | /* |
210 | * LL rotation. |
254 | * LL rotation. |
211 | */ |
255 | */ |
212 | top->lft = par->rgt; |
- | |
213 | if (top->lft != NULL) |
256 | REBALANCE_INSERT_LL(); |
214 | top->lft->par = top; |
- | |
215 | par->par = top->par; |
- | |
216 | top->par = par; |
- | |
217 | par->rgt = top; |
- | |
218 | par->balance = 0; |
- | |
219 | top->balance = 0; |
- | |
220 | *dpc = par; |
- | |
221 | } else { |
257 | } else { |
222 | /* |
258 | /* |
223 | * LR rotation. |
259 | * LR rotation. |
224 | */ |
260 | */ |
225 | ASSERT(par->balance == 1); |
261 | ASSERT(par->balance == 1); |
226 | 262 | ||
227 | gpa = par->rgt; |
- | |
228 | par->rgt = gpa->lft; |
- | |
229 | if (gpa->lft != NULL) |
- | |
230 | gpa->lft->par = par; |
263 | REBALANCE_INSERT_LR(); |
231 | gpa->lft = par; |
- | |
232 | par->par = gpa; |
- | |
233 | top->lft = gpa->rgt; |
- | |
234 | if (gpa->rgt != NULL) |
- | |
235 | gpa->rgt->par = top; |
- | |
236 | gpa->rgt = top; |
- | |
237 | gpa->par = top->par; |
- | |
238 | top->par = gpa; |
- | |
239 | - | ||
240 | if (gpa->balance == -1) { |
- | |
241 | par->balance = 0; |
- | |
242 | top->balance = 1; |
- | |
243 | } else if (gpa->balance == 0) { |
- | |
244 | par->balance = 0; |
- | |
245 | top->balance = 0; |
- | |
246 | } else { |
- | |
247 | par->balance = -1; |
- | |
248 | top->balance = 0; |
- | |
249 | } |
- | |
250 | gpa->balance = 0; |
- | |
251 | *dpc = gpa; |
- | |
252 | } |
264 | } |
253 | } else if (top->balance == 2) { |
265 | } else if (top->balance == 2) { |
254 | par = top->rgt; |
266 | par = top->rgt; |
255 | if (par->balance == 1) { |
267 | if (par->balance == 1) { |
256 | /* |
268 | /* |
257 | * RR rotation. |
269 | * RR rotation. |
258 | */ |
270 | */ |
259 | top->rgt = par->lft; |
- | |
260 | if (top->rgt != NULL) |
- | |
261 | top->rgt->par = top; |
271 | REBALANCE_INSERT_RR(); |
262 | par->par = top->par; |
- | |
263 | top->par = par; |
- | |
264 | par->lft = top; |
- | |
265 | par->balance = 0; |
- | |
266 | top->balance = 0; |
- | |
267 | *dpc = par; |
- | |
268 | } else { |
272 | } else { |
269 | /* |
273 | /* |
270 | * RL rotation. |
274 | * RL rotation. |
271 | */ |
275 | */ |
272 | ASSERT(par->balance == -1); |
276 | ASSERT(par->balance == -1); |
273 | 277 | ||
274 | gpa = par->lft; |
- | |
275 | par->lft = gpa->rgt; |
- | |
276 | if (gpa->rgt != NULL) |
- | |
277 | gpa->rgt->par = par; |
- | |
278 | gpa->rgt = par; |
- | |
279 | par->par = gpa; |
- | |
280 | top->rgt = gpa->lft; |
- | |
281 | if (gpa->lft != NULL) |
278 | REBALANCE_INSERT_RL(); |
282 | gpa->lft->par = top; |
- | |
283 | gpa->lft = top; |
- | |
284 | gpa->par = top->par; |
- | |
285 | top->par = gpa; |
- | |
286 | - | ||
287 | if (gpa->balance == 1) { |
- | |
288 | par->balance = 0; |
- | |
289 | top->balance = -1; |
- | |
290 | } else if (gpa->balance == 0) { |
- | |
291 | par->balance = 0; |
- | |
292 | top->balance = 0; |
- | |
293 | } else { |
- | |
294 | par->balance = 1; |
- | |
295 | top->balance = 0; |
- | |
296 | } |
- | |
297 | gpa->balance = 0; |
- | |
298 | *dpc = gpa; |
- | |
299 | } |
279 | } |
300 | } else { |
280 | } else { |
301 | /* |
281 | /* |
302 | * Balance is not broken, insertion is finised. |
282 | * Balance is not broken, insertion is finised. |
303 | */ |
283 | */ |
Line 349... | Line 329... | ||
349 | } |
329 | } |
350 | } |
330 | } |
351 | return 1; |
331 | return 1; |
352 | } |
332 | } |
353 | 333 | ||
354 | #define REBALANCE(DIR1, DIR2, SIGN) \ |
334 | #define REBALANCE_DELETE(DIR1, DIR2, SIGN) \ |
355 | if (cur->balance == -1 * SIGN) { \ |
335 | if (cur->balance == -1 * SIGN) { \ |
356 | par->balance = 0; \ |
336 | par->balance = 0; \ |
357 | gpa->balance = 1 * SIGN; \ |
337 | gpa->balance = 1 * SIGN; \ |
358 | if (gpa->DIR1) \ |
338 | if (gpa->DIR1) \ |
359 | gpa->DIR1->par = gpa; \ |
339 | gpa->DIR1->par = gpa; \ |
Line 372... | Line 352... | ||
372 | par->DIR2->par = par; \ |
352 | par->DIR2->par = par; \ |
373 | gpa->DIR1->par = gpa; \ |
353 | gpa->DIR1->par = gpa; \ |
374 | } \ |
354 | } \ |
375 | cur->balance = 0; |
355 | cur->balance = 0; |
376 | 356 | ||
377 | #define REBALANCE_LR() REBALANCE(lft, rgt, 1) |
357 | #define REBALANCE_DELETE_LR() REBALANCE_DELETE(lft, rgt, 1) |
378 | #define REBALANCE_RL() REBALANCE(rgt, lft, -1) |
358 | #define REBALANCE_DELETE_RL() REBALANCE_DELETE(rgt, lft, -1) |
379 | 359 | ||
380 | /** Delete a node from the AVL tree. |
360 | /** Delete a node from the AVL tree. |
381 | * |
361 | * |
382 | * Because multiple identical keys are allowed, the parent pointers are |
362 | * Because multiple identical keys are allowed, the parent pointers are |
383 | * essential during deletion. |
363 | * essential during deletion. |
Line 513... | Line 493... | ||
513 | /* |
493 | /* |
514 | * Repair balances and paternity of |
494 | * Repair balances and paternity of |
515 | * children, depending on the balance |
495 | * children, depending on the balance |
516 | * factor of the grand child (cur). |
496 | * factor of the grand child (cur). |
517 | */ |
497 | */ |
518 | REBALANCE_RL(); |
498 | REBALANCE_DELETE_RL(); |
519 | 499 | ||
520 | /* |
500 | /* |
521 | * Repair paternity. |
501 | * Repair paternity. |
522 | */ |
502 | */ |
523 | cur->par = gpa->par; |
503 | cur->par = gpa->par; |
Line 609... | Line 589... | ||
609 | /* |
589 | /* |
610 | * Repair balances and paternity of |
590 | * Repair balances and paternity of |
611 | * children, depending on the balance |
591 | * children, depending on the balance |
612 | * factor of the grand child (cur). |
592 | * factor of the grand child (cur). |
613 | */ |
593 | */ |
614 | REBALANCE_LR(); |
594 | REBALANCE_DELETE_LR(); |
615 | 595 | ||
616 | /* |
596 | /* |
617 | * Repair paternity. |
597 | * Repair paternity. |
618 | */ |
598 | */ |
619 | cur->par = gpa->par; |
599 | cur->par = gpa->par; |