Subversion Repositories HelenOS

Rev

Rev 2461 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2461 Rev 2496
Line 35... Line 35...
35
 * @brief   AVL tree implementation.
35
 * @brief   AVL tree implementation.
36
 *
36
 *
37
 * This file implements AVL tree type and operations.
37
 * This file implements AVL tree type and operations.
38
 *
38
 *
39
 * Implemented AVL tree has the following properties:
39
 * Implemented AVL tree has the following properties:
40
 * @li It is binary search tree with non-unique keys.
40
 * @li It is a binary search tree with non-unique keys.
41
 * @li Difference of heights of left and right subtree of every node is max 1.
41
 * @li Difference of heights of the left and the right subtree of every node is
-
 
42
 *     one at maximum.
42
 *
43
 *
43
 * Every node has pointer to its parent which allows insertion of multiple identical keys
44
 * Every node has a pointer to its parent which allows insertion of multiple
44
 * into tree.
45
 * identical keys into the tree.
45
 *
46
 *
46
 * Be careful of using this tree because of base atribute, which is added to every inserted
47
 * Be careful when using this tree because of the base atribute which is added
47
 * node key. There is no rule in which order nodes with the same key are visited.
48
 * to every inserted node key. There is no rule in which order nodes with the
-
 
49
 * same key are visited.
48
 */
50
 */
49
 
51
 
50
#include <adt/avl.h>
52
#include <adt/avl.h>
51
#include <debug.h>
53
#include <debug.h>
52
 
54
 
53
 
55
 
54
#define AVLTREE_LEFT 0
56
#define LEFT    0
55
#define AVLTREE_RIGHT 1
57
#define RIGHT   1
56
 
58
 
57
 
59
 
58
/** Search first occurence of given key in AVL tree.
60
/** Search for the first occurence of the given key in an AVL tree.
59
 *
61
 *
60
 * @param t AVL tree.
62
 * @param t AVL tree.
61
 * @param key Key to be searched.
63
 * @param key Key to be searched.
62
 *
64
 *
63
 * @return Pointer to node or NULL if there is no such key.
65
 * @return Pointer to a node or NULL if there is no such key.
64
 */
66
 */
65
avltree_node_t *avltree_search(avltree_t *t, uint64_t key)
67
avltree_node_t *avltree_search(avltree_t *t, uint64_t key)
66
{
68
{
67
    avltree_node_t *p;
69
    avltree_node_t *p;
68
   
70
   
Line 73... Line 75...
73
    while (p != NULL) {
75
    while (p != NULL) {
74
        if (p->key > key)
76
        if (p->key > key)
75
            p = p->lft;
77
            p = p->lft;
76
        else if (p->key < key)
78
        else if (p->key < key)
77
            p = p->rgt;
79
            p = p->rgt;
78
        else {
80
        else
79
            return p;
81
            return p;
80
        }
-
 
81
    }
82
    }
82
    return NULL;
83
    return NULL;
83
}
84
}
84
 
85
 
85
 
86
 
86
/** Find node with smallest key in AVL tree.
87
/** Find the node with the smallest key in an AVL tree.
87
 *
88
 *
88
 * @param t AVL tree.
89
 * @param t AVL tree.
89
 *
90
 *
90
 * @return Pointer to node or NULL if there is no node in the tree.
91
 * @return Pointer to a node or NULL if there is no node in the tree.
91
 */
92
 */
92
avltree_node_t *avltree_find_min(avltree_t *t)
93
avltree_node_t *avltree_find_min(avltree_t *t)
93
{
94
{
94
    avltree_node_t *p = t->root;
95
    avltree_node_t *p = t->root;
95
   
96
   
96
    /*
97
    /*
97
     * Check whether tree is empty.
98
     * Check whether the tree is empty.
98
     */
99
     */
-
 
100
    if (!p)
99
    if (!p) return NULL;
101
        return NULL;
100
   
102
   
101
    /*
103
    /*
102
     * Iteratively descend to the leftmost leaf in the tree.
104
     * Iteratively descend to the leftmost leaf in the tree.
103
     */
105
     */
104
    while (p->lft != NULL)
106
    while (p->lft != NULL)
Line 126... Line 128...
126
    /*
128
    /*
127
     * Creating absolute key.
129
     * Creating absolute key.
128
     */
130
     */
129
    key = newnode->key + t->base;
131
    key = newnode->key + t->base;
130
   
132
   
131
 
-
 
132
    /*
133
    /*
133
     * Iteratively descend to the leaf that can contain new node.
134
     * Iteratively descend to the leaf that can contain the new node.
134
     * Last node with non-zero balance in the way to leaf is stored as top -
135
     * Last node with non-zero balance in the way to leaf is stored as top -
135
     * it si place of possible balance fault.
136
     * it is a place of possible inbalance.
136
     */
137
     */
137
    dpc = &t->root;
138
    dpc = &t->root;
138
    gpa = NULL;
139
    gpa = NULL;
139
    top = t->root;
140
    top = t->root;
140
    while ((par = (*dpc)) != NULL) {
141
    while ((par = (*dpc)) != NULL) {
141
        if (par->balance != 0) {
142
        if (par->balance != 0) {
142
            top = par;
143
            top = par;
143
        }
144
        }
144
        gpa = par;
145
        gpa = par;
145
        dpc = par->key > key? &par->lft: &par->rgt;
146
        dpc = par->key > key ? &par->lft: &par->rgt;
146
    }
147
    }
147
 
148
 
148
    /*
149
    /*
149
     * Initialize new node.
150
     * Initialize new node.
150
     */
151
     */
Line 153... Line 154...
153
    newnode->rgt = NULL;
154
    newnode->rgt = NULL;
154
    newnode->par = gpa;
155
    newnode->par = gpa;
155
    newnode->balance = 0;
156
    newnode->balance = 0;
156
 
157
 
157
    /*
158
    /*
158
     * Insert first node into empty tree.
159
     * Insert first node into the empty tree.
159
     */
160
     */
160
    if (t->root == NULL) {
161
    if (t->root == NULL) {
161
        *dpc = newnode;
162
        *dpc = newnode;
162
        return;
163
        return;
163
    }
164
    }
Line 166... Line 167...
166
     * Insert new node into previously found leaf place.
167
     * Insert new node into previously found leaf place.
167
     */
168
     */
168
    *dpc = newnode;
169
    *dpc = newnode;
169
 
170
 
170
    /*
171
    /*
171
     * If tree contains one node - end.
172
     * If the tree contains one node - end.
172
     */
173
     */
173
    if (top == NULL) return;
174
    if (top == NULL)
-
 
175
        return;
174
 
176
 
175
    /*
177
    /*
176
     * Store pointer of top's father which points to the node with potentialy broken
178
     * Store pointer of top's father which points to the node with
177
     * balance (top).
179
     * potentially broken balance (top).
178
     */
180
     */
179
    if (top->par == NULL)
181
    if (top->par == NULL) {
180
        dpc = &t->root;
182
        dpc = &t->root;
181
    else
183
    } else {
182
        if (top->par->lft == top)
184
        if (top->par->lft == top)
183
            dpc = &(top->par->lft);
185
            dpc = &top->par->lft;
184
        else
186
        else
185
            dpc = &(top->par->rgt);
187
            dpc = &top->par->rgt;
-
 
188
    }
186
 
189
 
187
    /*
190
    /*
188
     * Repair all balances on the way from top node to newly inserted node.
191
     * Repair all balances on the way from top node to the newly inserted
-
 
192
     * node.
189
     */
193
     */
190
    par = top;
194
    par = top;
191
    while (par != newnode) {
195
    while (par != newnode) {
192
        if (par->key > key) {
196
        if (par->key > key) {
193
            par->balance--;
197
            par->balance--;
Line 197... Line 201...
197
            par = par->rgt;
201
            par = par->rgt;
198
        }
202
        }
199
    }
203
    }
200
   
204
   
201
    /*
205
    /*
202
     * To balance tree we must check and balance top node.
206
     * To balance the tree, we must check and balance top node.
203
     */
207
     */
204
    if (top->balance == -2) {
208
    if (top->balance == -2) {
205
        par = top->lft;
209
        par = top->lft;
206
        if (par->balance == -1) {
210
        if (par->balance == -1) {
207
            /*
211
            /*
208
             * LL rotation.
212
             * LL rotation.
209
             */
213
             */
210
            top->lft = par->rgt;
214
            top->lft = par->rgt;
211
            if (top->lft != NULL) top->lft->par = top;
215
            if (top->lft != NULL)
-
 
216
                top->lft->par = top;
212
            par->par = top->par;
217
            par->par = top->par;
213
            top->par = par;
218
            top->par = par;
214
            par->rgt = top;
219
            par->rgt = top;
215
            par->balance = top->balance = 0;
220
            par->balance = top->balance = 0;
216
            *dpc = par;
221
            *dpc = par;
Line 220... Line 225...
220
             */
225
             */
221
            ASSERT(par->balance == 1);
226
            ASSERT(par->balance == 1);
222
           
227
           
223
            gpa = par->rgt;
228
            gpa = par->rgt;
224
            par->rgt = gpa->lft;
229
            par->rgt = gpa->lft;
225
            if (gpa->lft != NULL) gpa->lft->par = par;
230
            if (gpa->lft != NULL)
-
 
231
                gpa->lft->par = par;
226
            gpa->lft = par;
232
            gpa->lft = par;
227
            par->par = gpa;
233
            par->par = gpa;
228
            top->lft = gpa->rgt;
234
            top->lft = gpa->rgt;
229
            if (gpa->rgt != NULL) gpa->rgt->par = top;
235
            if (gpa->rgt != NULL)
-
 
236
                gpa->rgt->par = top;
230
            gpa->rgt = top;
237
            gpa->rgt = top;
231
            gpa->par = top->par;
238
            gpa->par = top->par;
232
            top->par = gpa;
239
            top->par = gpa;
233
           
240
           
234
            if (gpa->balance == -1) {
241
            if (gpa->balance == -1) {
Line 248... Line 255...
248
        if (par->balance == 1) {
255
        if (par->balance == 1) {
249
            /*
256
            /*
250
             * RR rotation.
257
             * RR rotation.
251
             */
258
             */
252
            top->rgt = par->lft;
259
            top->rgt = par->lft;
253
            if (top->rgt != NULL) top->rgt->par = top;
260
            if (top->rgt != NULL)
-
 
261
                top->rgt->par = top;
254
            par->par = top->par;
262
            par->par = top->par;
255
            top->par = par;
263
            top->par = par;
256
            par->lft = top;
264
            par->lft = top;
257
            par->balance = top->balance = 0;
265
            par->balance = top->balance = 0;
258
            *dpc = par;
266
            *dpc = par;
Line 262... Line 270...
262
             */
270
             */
263
            ASSERT(par->balance == -1);
271
            ASSERT(par->balance == -1);
264
           
272
           
265
            gpa = par->lft;
273
            gpa = par->lft;
266
            par->lft = gpa->rgt;
274
            par->lft = gpa->rgt;
267
            if (gpa->rgt != NULL) gpa->rgt->par = par;
275
            if (gpa->rgt != NULL)
-
 
276
                gpa->rgt->par = par;
268
            gpa->rgt = par;
277
            gpa->rgt = par;
269
            par->par = gpa;
278
            par->par = gpa;
270
            top->rgt = gpa->lft;
279
            top->rgt = gpa->lft;
271
            if (gpa->lft != NULL) gpa->lft->par = top;
280
            if (gpa->lft != NULL)
-
 
281
                gpa->lft->par = top;
272
            gpa->lft = top;
282
            gpa->lft = top;
273
            gpa->par = top->par;
283
            gpa->par = top->par;
274
            top->par = gpa;
284
            top->par = gpa;
275
 
285
 
276
            if (gpa->balance == 1) {
286
            if (gpa->balance == 1) {
Line 292... Line 302...
292
        return;
302
        return;
293
    }
303
    }
294
 
304
 
295
}
305
}
296
 
306
 
297
/** Delete node from AVL tree.
307
/** Delete a node from the AVL tree.
298
 *
308
 *
299
 * Because of allowed multiple identical keys parent pointers are essential
309
 * Because multiple identical keys are allowed, the parent pointers are
300
 * during deletition.
310
 * essential during deletion.
301
 *
311
 *
302
 * @param t AVL tree structure.
312
 * @param t AVL tree structure.
303
 * @param node Address of node which will be deleted.
313
 * @param node Address of the node which will be deleted.
304
 */
314
 */
305
void avltree_delete(avltree_t *t, avltree_node_t *node)
315
void avltree_delete(avltree_t *t, avltree_node_t *node)
306
{
316
{
307
    avltree_node_t *cur;
317
    avltree_node_t *cur;
308
    avltree_node_t *par;
318
    avltree_node_t *par;
Line 310... Line 320...
310
    uint8_t dir;
320
    uint8_t dir;
311
 
321
 
312
    ASSERT(t);
322
    ASSERT(t);
313
    ASSERT(node);
323
    ASSERT(node);
314
   
324
   
315
   
-
 
316
    if (node->lft == NULL) {
325
    if (node->lft == NULL) {
317
        if (node->rgt) {
326
        if (node->rgt) {
318
            /*
327
            /*
319
             * Replace node with its only right son.
328
             * Replace the node with its only right son.
320
             *
329
             *
321
             * Balance of right son will be repaired in balancing cycle.
330
             * Balance of the right son will be repaired in the
-
 
331
             * balancing cycle.
322
             */
332
             */
323
            cur = node->rgt;
333
            cur = node->rgt;
324
            cur->par = node->par;
334
            cur->par = node->par;
325
            gpa = cur;
335
            gpa = cur;
326
            dir = AVLTREE_RIGHT;
336
            dir = RIGHT;
327
            cur->balance = node->balance;
337
            cur->balance = node->balance;
328
        } else {
338
        } else {
329
            if (node->par == NULL) {
339
            if (node->par == NULL) {
330
                /*
340
                /*
331
                 * Tree has only one node - it will be empty tree and balancing can end.
341
                 * The tree has only one node - it will become
-
 
342
                 * an empty tree and the balancing can end.
332
                 */
343
                 */
333
                t->root = NULL;
344
                t->root = NULL;
334
                return;
345
                return;
335
            }
346
            }
336
            /*
347
            /*
337
             * Node has no child, will be deleted with no substitution.
348
             * The node has no child, it will be deleted with no
-
 
349
             * substitution.
338
             */
350
             */
339
            gpa = node->par;
351
            gpa = node->par;
340
            cur = NULL;
352
            cur = NULL;
341
            dir = (gpa->lft == node)? AVLTREE_LEFT: AVLTREE_RIGHT;
353
            dir = (gpa->lft == node) ? LEFT: RIGHT;
342
        }
354
        }
343
    } else {
355
    } else {
344
        /*
356
        /*
345
         * Node has left and right son. Find a node with smallest key in left subtree
357
         * The node has left and right son. Find a node with the
-
 
358
         * smallest key in the left subtree and replace the deleted node
346
         * and replace deleted node with that node.
359
         * with that node.
347
         */
360
         */
348
        for (cur = node->lft; cur->rgt != NULL; cur = cur->rgt)
361
        for (cur = node->lft; cur->rgt != NULL; cur = cur->rgt)
349
            ;
362
            ;
350
       
-
 
351
        //cur obsahuje uzel, ktery vlozim misto uzlu node
-
 
352
       
363
 
353
        if (cur != node->lft) {
364
        if (cur != node->lft) {
354
            /*
365
            /*
355
             * The most right node of deleted node's left subtree was found. Replace
366
             * The rightmost node of the deleted node's left subtree
-
 
367
             * was found. Replace the deleted node with this node.
356
             * deleted node with this node. Cutting founded node has two cases in
368
             * Cutting off of the found node has two cases that
357
             * dependence on its left son.
369
             * depend on its left son.
358
             */
370
             */
359
            if (cur->lft) {
371
            if (cur->lft) {
360
                /*
372
                /*
361
                 * Founded node has left son.
373
                 * The found node has a left son.
362
                 */
374
                 */
363
                gpa = cur->lft;
375
                gpa = cur->lft;
364
                gpa->par = cur->par;
376
                gpa->par = cur->par;
365
                dir = AVLTREE_LEFT;
377
                dir = LEFT;
366
                gpa->balance = cur->balance;
378
                gpa->balance = cur->balance;
367
            } else {
379
            } else {
368
                dir = AVLTREE_RIGHT;
380
                dir = RIGHT;
369
                gpa = cur->par;
381
                gpa = cur->par;
370
            }
382
            }
371
            cur->par->rgt = cur->lft;
383
            cur->par->rgt = cur->lft;
372
            cur->lft = node->lft;
384
            cur->lft = node->lft;
373
            cur->lft->par = cur;
385
            cur->lft->par = cur;
374
        } else {
386
        } else {
375
            /*
387
            /*
-
 
388
             * The left son of the node hasn't got a right son. The
376
             * Left son of node hasn't got right son. Left son will take deleted node's place.
389
             * left son will take the deleted node's place.
377
             */
390
             */
378
            dir = AVLTREE_LEFT;
391
            dir = LEFT;
379
            gpa = cur;
392
            gpa = cur;
380
        }
393
        }
-
 
394
        if (node->rgt)
381
        if (node->rgt) node->rgt->par = cur;
395
            node->rgt->par = cur;
382
        cur->rgt = node->rgt;
396
        cur->rgt = node->rgt;
383
        cur->balance = node->balance;
397
        cur->balance = node->balance;
384
        cur->par = node->par;
398
        cur->par = node->par;
385
    }
399
    }
386
   
400
   
387
    /*
401
    /*
388
     * Repair parent nodes pointer which pointed previously to deleted node.
402
     * Repair the parent node's pointer which pointed previously to the
-
 
403
     * deleted node.
389
     */
404
     */
390
    if (node->par == NULL) {
405
    if (node->par == NULL) {
391
        t->root = cur;
406
        t->root = cur;
392
    } else {
407
    } else {
393
        if (node->par->lft == node) {
408
        if (node->par->lft == node) {
Line 396... Line 411...
396
            node->par->rgt = cur;
411
            node->par->rgt = cur;
397
        }
412
        }
398
    }
413
    }
399
   
414
   
400
    /*
415
    /*
401
     * Repair cycle which repairs balances of nodes in way from cutted noded down to root.
416
     * Repair cycle which repairs balances of nodes on the way from from the
-
 
417
     * cut-off node up to the root.
402
     */
418
     */
403
    for(;;) {
419
    for (;;) {
404
        if (dir == AVLTREE_LEFT) {
420
        if (dir == LEFT) {
405
            /*
421
            /*
406
             * Deletition was made in left subtree.
422
             * Deletion was made in the left subtree.
407
             */
423
             */
408
            gpa->balance++;
424
            gpa->balance++;
409
            if (gpa->balance == +1) {
425
            if (gpa->balance == 1) {
410
                /*
426
                /*
411
                 * Stop balancing, tree is balanced.
427
                 * Stop balancing, the tree is balanced.
412
                 */
428
                 */
413
                break;
429
                break;
414
            } else if (gpa->balance == +2) {
430
            } else if (gpa->balance == 2) {
415
                /*
431
                /*
416
                 * Bad balance, heights of left and right subtrees differs more then is allowed.
432
                 * Bad balance, heights of left and right
-
 
433
                 * subtrees differ more than by one.
417
                 */
434
                 */
418
                par = gpa->rgt;
435
                par = gpa->rgt;
419
 
436
 
420
                if (par->balance == -1) {
437
                if (par->balance == -1) {
421
                    /*
438
                    /*
Line 427... Line 444...
427
                    cur->rgt = par;
444
                    cur->rgt = par;
428
                    gpa->rgt = cur->lft;
445
                    gpa->rgt = cur->lft;
429
                    cur->lft = gpa;
446
                    cur->lft = gpa;
430
                   
447
                   
431
                    /*
448
                    /*
432
                     * Repair balances and paternity of childs in dependence on
449
                     * Repair balances and paternity of
-
 
450
                     * children, depending on the balance
433
                     * balance factor of grand child (cur).
451
                     * factor of the grand child (cur).
434
                     */
452
                     */
435
                    if (cur->balance == +1) {
453
                    if (cur->balance == 1) {
436
                        par->balance = 0;
454
                        par->balance = 0;
437
                        gpa->balance = -1;
455
                        gpa->balance = -1;
-
 
456
                        if (gpa->rgt)
438
                        if (gpa->rgt) gpa->rgt->par = gpa;
457
                            gpa->rgt->par = gpa;
439
                        par->lft->par = par;
458
                        par->lft->par = par;
440
                    } else if (cur->balance == 0) {
459
                    } else if (cur->balance == 0) {
441
                        par->balance = gpa->balance = 0;
460
                        par->balance = gpa->balance = 0;
-
 
461
                        if (gpa->rgt)
442
                        if (gpa->rgt) gpa->rgt->par = gpa;
462
                            gpa->rgt->par = gpa;
-
 
463
                        if (par->lft)
443
                        if (par->lft) par->lft->par = par;
464
                            par->lft->par = par;
444
                    } else {
465
                    } else {
445
                        par->balance = +1;
466
                        par->balance = 1;
446
                        gpa->balance = 0;
467
                        gpa->balance = 0;
-
 
468
                        if (par->lft)
447
                        if (par->lft) par->lft->par = par;
469
                            par->lft->par = par;
448
                        gpa->rgt->par = gpa;
470
                        gpa->rgt->par = gpa;
449
                    }
471
                    }
450
                    cur->balance = 0;
472
                    cur->balance = 0;
451
                   
473
                   
452
                    /*
474
                    /*
Line 455... Line 477...
455
                    cur->par = gpa->par;
477
                    cur->par = gpa->par;
456
                    gpa->par = cur;
478
                    gpa->par = cur;
457
                    par->par = cur;
479
                    par->par = cur;
458
 
480
 
459
                    /*
481
                    /*
-
 
482
                     * Repair the pointer which pointed to
460
                     * Repair pointer which pointed to balanced node. If it was root then balancing
483
                     * the balanced node. If it was root
-
 
484
                     * then the balancing is finished.
-
 
485
                     * Otherwise continue with the next
461
                     * is finished else continue in next iteration (parent node).
486
                     * iteration (parent node).
462
                     */
487
                     */
463
                    if (cur->par == NULL) {
488
                    if (cur->par == NULL) {
464
                        t->root = cur; 
489
                        t->root = cur; 
465
                        break;
490
                        break;
466
                    } else
491
                    } else {
467
                        if (cur->par->lft == gpa) {
492
                        if (cur->par->lft == gpa) {
468
                            cur->par->lft = cur;
493
                            cur->par->lft = cur;
469
                            dir = AVLTREE_LEFT;
494
                            dir = LEFT;
470
                        } else {
495
                        } else {
471
                            cur->par->rgt = cur;
496
                            cur->par->rgt = cur;
472
                            dir = AVLTREE_RIGHT;
497
                            dir = RIGHT;
473
                        }
498
                        }
-
 
499
                    }
474
                    gpa = cur->par;
500
                    gpa = cur->par;
475
                } else {
501
                } else {
476
                    /*
502
                    /*
477
                     * RR rotation.
503
                     * RR rotation.
478
                     */
504
                     */
479
                   
505
                   
480
                    gpa->rgt = par->lft;
506
                    gpa->rgt = par->lft;
-
 
507
                    if (par->lft)
481
                    if (par->lft) par->lft->par = gpa;
508
                        par->lft->par = gpa;
482
                    par->lft = gpa;
509
                    par->lft = gpa;
483
                   
510
                   
484
                    /*
511
                    /*
485
                     * Repair paternity.
512
                     * Repair paternity.
486
                     */
513
                     */
487
                    par->par = gpa->par;
514
                    par->par = gpa->par;
488
                    gpa->par = par;
515
                    gpa->par = par;
489
                   
516
                   
490
                    if (par->balance == 0) {
517
                    if (par->balance == 0) {
491
                        /*
518
                        /*
-
 
519
                         * The right child of the
-
 
520
                         * balanced node is balanced,
492
                         * Right child of balanced node is balanced, after RR rotation is done, whole
521
                         * after RR rotation is done,
493
                         * tree will be balanced.
522
                         * the whole tree will be
-
 
523
                         * balanced.
494
                         */
524
                         */
495
                        par->balance = -1;
525
                        par->balance = -1;
496
                        gpa->balance = +1;
526
                        gpa->balance = 1;
497
 
527
 
498
                        /*
528
                        /*
-
 
529
                         * Repair the pointer which
499
                         * Repair pointer which pointed to balanced node and finish balancing.
530
                         * pointed to the balanced node
-
 
531
                         * and finish balancing.
500
                         */
532
                         */
501
                        if (par->par == NULL) {
533
                        if (par->par == NULL) {
502
                            t->root = par; 
534
                            t->root = par; 
503
                        } else
535
                        } else {
504
                            if (par->par->lft == gpa) {
536
                            if (par->par->lft ==
-
 
537
                                gpa) {
505
                                par->par->lft = par;
538
                                par->par->lft =
-
 
539
                                    par;
506
                            } else {
540
                            } else {
507
                                par->par->rgt = par;
541
                                par->par->rgt =
-
 
542
                                    par;
508
                            }
543
                            }
-
 
544
                        }
509
                        break;
545
                        break;
510
                    } else {
546
                    } else {
511
                        par->balance = gpa->balance = 0;
547
                        par->balance = gpa->balance = 0;
512
                        /*
548
                        /*
-
 
549
                         * Repair the pointer which
-
 
550
                         * pointed to the balanced node.
513
                         * Repair pointer which pointed to balanced node. If it was root then balancing
551
                         * If it was root then balancing
-
 
552
                         * is finished. Otherwise
-
 
553
                         * continue with the next
514
                         * is finished else continue in next iteration (parent node).
554
                         * iteration (parent node).
515
                         */
555
                         */
516
                        if (par->par == NULL) {
556
                        if (par->par == NULL) {
517
                            t->root = par; 
557
                            t->root = par; 
518
                            break;
558
                            break;
519
                        } else {
559
                        } else {   
-
 
560
                            if (par->par->lft ==
520
                           
561
                                gpa) {
521
                            if (par->par->lft == gpa) {
562
                                par->par->lft =
522
                                par->par->lft = par;
563
                                    par;
523
                                dir = AVLTREE_LEFT;
564
                                dir = LEFT;
524
                            } else {
565
                            } else {
525
                                par->par->rgt = par;
566
                                par->par->rgt =
-
 
567
                                    par;
526
                                dir = AVLTREE_RIGHT;
568
                                dir = RIGHT;
527
                            }
569
                            }
528
                        }
570
                        }
529
                    }
571
                    }
530
                    gpa = par->par;
572
                    gpa = par->par;
531
                }
573
                }
532
            } else {
574
            } else {
533
                /*
575
                /*
-
 
576
                 * Repair the pointer which pointed to the
534
                 * Repair pointer which pointed to balanced node. If it was root then balancing
577
                 * balanced node. If it was root then balancing
535
                 * is finished else continue in next iteration (parent node).
578
                 * is finished else continue with the next
-
 
579
                 * iteration (parent node).
536
                 */
580
                 */
537
                if (!gpa->par) break;
581
                if (!gpa->par)
-
 
582
                    break;
538
 
583
 
539
                if (gpa->par->lft == gpa) {
584
                if (gpa->par->lft == gpa) {
540
                    dir = AVLTREE_LEFT;
585
                    dir = LEFT;
541
                } else {
586
                } else {
542
                    dir = AVLTREE_RIGHT;
587
                    dir = RIGHT;
543
                }
588
                }
544
                gpa = gpa->par;
589
                gpa = gpa->par;
545
            }
590
            }
546
        } else {
591
        } else {
547
            /*
592
            /*
548
             * Deletition was made in right subtree.
593
             * Deletion was made in the right subtree.
549
             */
594
             */
550
            gpa->balance--;
595
            gpa->balance--;
551
            if (gpa->balance == -1) {
596
            if (gpa->balance == -1) {
552
                /*
597
                /*
553
                 * Stop balancing, tree is balanced.
598
                 * Stop balancing, the tree is balanced.
554
                 */
599
                 */
555
                break;
600
                break;
556
            } else if (gpa->balance == -2) {
601
            } else if (gpa->balance == -2) {
557
                /*
602
                /*
558
                 * Bad balance, heights of left and right subtrees differs more then is allowed.
603
                 * Bad balance, heights of left and right
-
 
604
                 * subtrees differ more than by one.
559
                 */
605
                 */
560
                par = gpa->lft;
606
                par = gpa->lft;
561
               
607
               
562
                if (par->balance == +1) {
608
                if (par->balance == 1) {
563
                    /*
609
                    /*
564
                     * LR rotation.
610
                     * LR rotation.
565
                     */
611
                     */
566
                   
612
                   
567
                    cur = par->rgt;
613
                    cur = par->rgt;
Line 569... Line 615...
569
                    cur->lft = par;
615
                    cur->lft = par;
570
                    gpa->lft = cur->rgt;
616
                    gpa->lft = cur->rgt;
571
                    cur->rgt = gpa;
617
                    cur->rgt = gpa;
572
                   
618
                   
573
                    /*
619
                    /*
574
                     * Repair balances and paternity of childs in dependence on
620
                     * Repair balances and paternity of
-
 
621
                     * children, depending on the balance
575
                     * balance factor of grand child (cur).
622
                     * factor of the grand child (cur).
576
                     */
623
                     */
577
                    if (cur->balance == -1) {
624
                    if (cur->balance == -1) {
578
                        par->balance = 0;
625
                        par->balance = 0;
579
                        gpa->balance = +1;
626
                        gpa->balance = 1;
-
 
627
                        if (gpa->lft)
580
                        if (gpa->lft) gpa->lft->par = gpa;
628
                            gpa->lft->par = gpa;
581
                        par->rgt->par = par;
629
                        par->rgt->par = par;
582
                    } else if (cur->balance == 0) {
630
                    } else if (cur->balance == 0) {
583
                        par->balance = gpa->balance = 0;
631
                        par->balance = gpa->balance = 0;
-
 
632
                        if (gpa->lft)
584
                        if (gpa->lft) gpa->lft->par = gpa;
633
                            gpa->lft->par = gpa;
-
 
634
                        if (par->rgt)
585
                        if (par->rgt) par->rgt->par = par;
635
                            par->rgt->par = par;
586
                    } else {
636
                    } else {
587
                        par->balance = -1;
637
                        par->balance = -1;
588
                        gpa->balance = 0;
638
                        gpa->balance = 0;
-
 
639
                        if (par->rgt)
589
                        if (par->rgt) par->rgt->par = par;
640
                            par->rgt->par = par;
590
                        gpa->lft->par = gpa;
641
                        gpa->lft->par = gpa;
591
                    }
642
                    }
592
                    cur->balance = 0;
643
                    cur->balance = 0;
593
 
644
 
594
                    /*
645
                    /*
Line 597... Line 648...
597
                    cur->par = gpa->par;
648
                    cur->par = gpa->par;
598
                    gpa->par = cur;
649
                    gpa->par = cur;
599
                    par->par = cur;
650
                    par->par = cur;
600
 
651
 
601
                    /*
652
                    /*
-
 
653
                     * Repair the pointer which pointed to
602
                     * Repair pointer which pointed to balanced node. If it was root then balancing
654
                     * the balanced node. If it was root
-
 
655
                     * then balancing is finished. Otherwise
603
                     * is finished else continue in next iteration (parent node).
656
                     * continue with the next iteration
-
 
657
                     * (parent node).
604
                     */
658
                     */
605
                    if (cur->par == NULL) {
659
                    if (cur->par == NULL) {
606
                        t->root = cur; 
660
                        t->root = cur; 
607
                        break;
661
                        break;
608
                    } else
662
                    } else {
609
                        if (cur->par->lft == gpa) {
663
                        if (cur->par->lft == gpa) {
610
                            cur->par->lft = cur;
664
                            cur->par->lft = cur;
611
                            dir = AVLTREE_LEFT;
665
                            dir = LEFT;
612
                        } else {
666
                        } else {
613
                            cur->par->rgt = cur;
667
                            cur->par->rgt = cur;
614
                            dir = AVLTREE_RIGHT;
668
                            dir = RIGHT;
615
                        }
669
                        }
-
 
670
                    }
616
                    gpa = cur->par;
671
                    gpa = cur->par;
617
                } else {
672
                } else {
618
                    /*
673
                    /*
619
                     * LL rotation.
674
                     * LL rotation.
620
                     */
675
                     */
621
                   
676
                   
622
                    gpa->lft = par->rgt;
677
                    gpa->lft = par->rgt;
-
 
678
                    if (par->rgt)
623
                    if (par->rgt) par->rgt->par = gpa;
679
                        par->rgt->par = gpa;
624
                    par->rgt = gpa;
680
                    par->rgt = gpa;
625
                    /*
681
                    /*
626
                     * Repair paternity.
682
                     * Repair paternity.
627
                     */
683
                     */
628
                    par->par = gpa->par;
684
                    par->par = gpa->par;
629
                    gpa->par = par;
685
                    gpa->par = par;
630
                   
686
                   
631
                    if (par->balance == 0) {
687
                    if (par->balance == 0) {
632
                        /*
688
                        /*
-
 
689
                         * The left child of the
633
                         * Left child of balanced node is balanced, after RR rotation is done, whole
690
                         * balanced node is balanced,
-
 
691
                         * after LL rotation is done,
634
                         * tree will be balanced.
692
                         * the whole tree will be
-
 
693
                         * balanced.
635
                         */
694
                         */
636
                        par->balance = +1;
695
                        par->balance = 1;
637
                        gpa->balance = -1;
696
                        gpa->balance = -1;
638
                       
697
                       
639
                        /*
698
                        /*
-
 
699
                         * Repair the pointer which
640
                         * Repair pointer which pointed to balanced node and finish balancing.
700
                         * pointed to the balanced node
-
 
701
                         * and finish balancing.
641
                         */
702
                         */
642
                        if (par->par == NULL) {
703
                        if (par->par == NULL) {
643
                            t->root = par;
704
                            t->root = par;
644
                        } else
705
                        } else {
645
                            if (par->par->lft == gpa) {
706
                            if (par->par->lft ==
-
 
707
                                gpa) {
646
                                par->par->lft = par;
708
                                par->par->lft =
-
 
709
                                    par;
647
                            } else {
710
                            } else {
648
                                par->par->rgt = par;
711
                                par->par->rgt =
-
 
712
                                    par;
649
                            }
713
                            }
-
 
714
                        }
650
                        break;
715
                        break;
651
                    } else {
716
                    } else {
652
                        par->balance = gpa->balance = 0;
717
                        par->balance = gpa->balance = 0;
653
                       
718
                       
654
                        /*
719
                        /*
-
 
720
                         * Repair the pointer which
-
 
721
                         * pointed to the balanced node.
655
                         * Repair pointer which pointed to balanced node. If it was root then balancing
722
                         * If it was root then balancing
-
 
723
                         * is finished. Otherwise
-
 
724
                         * continue with the next
656
                         * is finished else continue in next iteration (parent node).
725
                         * iteration (parent node).
657
                         */
726
                         */
658
                        if (par->par == NULL) {
727
                        if (par->par == NULL) {
659
                            t->root = par;
728
                            t->root = par;
660
                            break;
729
                            break;
661
                        } else {
730
                        } else {
662
                            if (par->par->lft == gpa) { //v cyklu jsem ani jednou neskocil - cur nema praveho syna
731
                            if (par->par->lft ==
-
 
732
                                gpa) {
663
                                par->par->lft = par;
733
                                par->par->lft =
-
 
734
                                    par;
664
                                dir = AVLTREE_LEFT;
735
                                dir = LEFT;
665
                            } else {
736
                            } else {
666
                                par->par->rgt = par;
737
                                par->par->rgt =
-
 
738
                                    par;
667
                                dir = AVLTREE_RIGHT;
739
                                dir = RIGHT;
668
                            }
740
                            }
669
                        }
741
                        }
670
                    }
742
                    }
671
                    gpa = par->par;
743
                    gpa = par->par;
672
                }
744
                }
673
            } else {
745
            } else {
674
                /*
746
                /*
-
 
747
                 * Repair the pointer which pointed to the
675
                 * Repair pointer which pointed to balanced node. If it was root then balancing
748
                 * balanced node. If it was root then balancing
676
                 * is finished else continue in next iteration (parent node).
749
                 * is finished. Otherwise continue with the next
-
 
750
                 * iteration (parent node).
677
                 */
751
                 */
678
                if (!gpa->par) break;
752
                if (!gpa->par)
-
 
753
                    break;
679
 
754
 
680
                if (gpa->par->lft == gpa) {
755
                if (gpa->par->lft == gpa) {
681
                    dir = AVLTREE_LEFT;
756
                    dir = LEFT;
682
                } else {
757
                } else {
683
                    dir = AVLTREE_RIGHT;
758
                    dir = RIGHT;
684
                }
759
                }
685
                gpa = gpa->par;
760
                gpa = gpa->par;
686
            }
761
            }
687
        }
762
        }
688
    }
763
    }
689
}
764
}
690
 
765
 
691
 
766
 
692
/** Delete node from AVL tree with the smallest key.
767
/** Delete a node with the smallest key from the AVL tree.
693
 *
768
 *
694
 * @param t AVL tree structure.
769
 * @param t AVL tree structure.
695
 */
770
 */
696
bool avltree_delete_min(avltree_t *t)
771
bool avltree_delete_min(avltree_t *t)
697
{
772
{
698
    avltree_node_t *node;
773
    avltree_node_t *node;
699
   
774
   
700
    /*
775
    /*
701
     * Start search of smallest key in tree in the root node and
776
     * Start searching for the smallest key in the tree starting in the root
702
     * continue in cycle to the most left node in the tree which
777
     * node and continue in cycle to the leftmost node in the tree (which
703
     * must have smallest key.
778
     * must have the smallest key).
704
     */
779
     */
-
 
780
     
705
    node = t->root;
781
    node = t->root;
-
 
782
    if (!node)
706
    if (!node) return false;
783
        return false;
707
   
784
   
708
    while (node->lft != NULL)
785
    while (node->lft != NULL)
709
        node = node->lft;
786
        node = node->lft;
710
   
787
   
711
    /*
-
 
712
     * Use avltree_delete function to delete node from tree.
-
 
713
     */
-
 
714
    avltree_delete(t,node);
788
    avltree_delete(t, node);
715
 
789
 
716
    return true;
790
    return true;
717
}
791
}
-
 
792
 
-
 
793
/** @}
-
 
794
 */