Subversion Repositories HelenOS

Rev

Rev 2499 | Rev 2503 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2499 Rev 2501
1
/*
1
/*
2
 * Copyright (c) 2007 Vojtech Mencl
2
 * Copyright (c) 2007 Vojtech Mencl
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup genericadt
29
/** @addtogroup genericadt
30
 * @{
30
 * @{
31
 */
31
 */
32
 
32
 
33
/**
33
/**
34
 * @file
34
 * @file
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 a 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 the left and the right subtree of every node is
41
 * @li Difference of heights of the left and the right subtree of every node is
42
 *     one at maximum.
42
 *     one at maximum.
43
 *
43
 *
44
 * Every node has a pointer to its parent which allows insertion of multiple
44
 * Every node has a pointer to its parent which allows insertion of multiple
45
 * identical keys into the tree.
45
 * identical keys into the tree.
46
 *
46
 *
47
 * Be careful when using this tree because of the base atribute which is added
47
 * Be careful when using this tree because of the base atribute which is added
48
 * to every inserted node key. There is no rule in which order nodes with the
48
 * to every inserted node key. There is no rule in which order nodes with the
49
 * same key are visited.
49
 * same key are visited.
50
 */
50
 */
51
 
51
 
52
#include <adt/avl.h>
52
#include <adt/avl.h>
53
#include <debug.h>
53
#include <debug.h>
54
 
54
 
55
 
-
 
56
#define LEFT    0
55
#define LEFT    0
57
#define RIGHT   1
56
#define RIGHT   1
58
 
57
 
59
 
-
 
60
/** Search for the first occurence of the given key in an AVL tree.
58
/** Search for the first occurence of the given key in an AVL tree.
61
 *
59
 *
62
 * @param t AVL tree.
60
 * @param t AVL tree.
63
 * @param key Key to be searched.
61
 * @param key Key to be searched.
64
 *
62
 *
65
 * @return Pointer to a node or NULL if there is no such key.
63
 * @return Pointer to a node or NULL if there is no such key.
66
 */
64
 */
67
avltree_node_t *avltree_search(avltree_t *t, uint64_t key)
65
avltree_node_t *avltree_search(avltree_t *t, avltree_key_t key)
68
{
66
{
69
    avltree_node_t *p;
67
    avltree_node_t *p;
70
   
68
   
71
    /*
69
    /*
72
     * Iteratively descend to the leaf that can contain the searched key.
70
     * Iteratively descend to the leaf that can contain the searched key.
73
     */
71
     */
74
    p = t->root;
72
    p = t->root;
75
    while (p != NULL) {
73
    while (p != NULL) {
76
        if (p->key > key)
74
        if (p->key > key)
77
            p = p->lft;
75
            p = p->lft;
78
        else if (p->key < key)
76
        else if (p->key < key)
79
            p = p->rgt;
77
            p = p->rgt;
80
        else
78
        else
81
            return p;
79
            return p;
82
    }
80
    }
83
    return NULL;
81
    return NULL;
84
}
82
}
85
 
83
 
86
 
84
 
87
/** Find the node with the smallest key in an AVL tree.
85
/** Find the node with the smallest key in an AVL tree.
88
 *
86
 *
89
 * @param t AVL tree.
87
 * @param t AVL tree.
90
 *
88
 *
91
 * @return Pointer to a node or NULL if there is no node in the tree.
89
 * @return Pointer to a node or NULL if there is no node in the tree.
92
 */
90
 */
93
avltree_node_t *avltree_find_min(avltree_t *t)
91
avltree_node_t *avltree_find_min(avltree_t *t)
94
{
92
{
95
    avltree_node_t *p = t->root;
93
    avltree_node_t *p = t->root;
96
   
94
   
97
    /*
95
    /*
98
     * Check whether the tree is empty.
96
     * Check whether the tree is empty.
99
     */
97
     */
100
    if (!p)
98
    if (!p)
101
        return NULL;
99
        return NULL;
102
   
100
   
103
    /*
101
    /*
104
     * Iteratively descend to the leftmost leaf in the tree.
102
     * Iteratively descend to the leftmost leaf in the tree.
105
     */
103
     */
106
    while (p->lft != NULL)
104
    while (p->lft != NULL)
107
        p = p->lft;
105
        p = p->lft;
108
   
106
   
109
    return p;
107
    return p;
110
}
108
}
111
 
109
 
112
/** Insert new node into AVL tree.
110
/** Insert new node into AVL tree.
113
 *
111
 *
114
 * @param t AVL tree.
112
 * @param t AVL tree.
115
 * @param newnode New node to be inserted.
113
 * @param newnode New node to be inserted.
116
 */
114
 */
117
void avltree_insert(avltree_t *t, avltree_node_t *newnode)
115
void avltree_insert(avltree_t *t, avltree_node_t *newnode)
118
{  
116
{  
119
    avltree_node_t *par;
117
    avltree_node_t *par;
120
    avltree_node_t *gpa;
118
    avltree_node_t *gpa;
121
    avltree_node_t *top;
119
    avltree_node_t *top;
122
    avltree_node_t **dpc;
120
    avltree_node_t **dpc;
123
    uint64_t key;
121
    avltree_key_t key;
124
 
122
 
125
    ASSERT(t);
123
    ASSERT(t);
126
    ASSERT(newnode);
124
    ASSERT(newnode);
127
 
125
 
128
    /*
126
    /*
129
     * Creating absolute key.
127
     * Creating absolute key.
130
     */
128
     */
131
    key = newnode->key + t->base;
129
    key = newnode->key + t->base;
132
   
130
   
133
    /*
131
    /*
134
     * Iteratively descend to the leaf that can contain the new node.
132
     * Iteratively descend to the leaf that can contain the new node.
135
     * Last node with non-zero balance in the way to leaf is stored as top -
133
     * Last node with non-zero balance in the way to leaf is stored as top -
136
     * it is a place of possible inbalance.
134
     * it is a place of possible inbalance.
137
     */
135
     */
138
    dpc = &t->root;
136
    dpc = &t->root;
139
    gpa = NULL;
137
    gpa = NULL;
140
    top = t->root;
138
    top = t->root;
141
    while ((par = (*dpc)) != NULL) {
139
    while ((par = (*dpc)) != NULL) {
142
        if (par->balance != 0) {
140
        if (par->balance != 0) {
143
            top = par;
141
            top = par;
144
        }
142
        }
145
        gpa = par;
143
        gpa = par;
146
        dpc = par->key > key ? &par->lft: &par->rgt;
144
        dpc = par->key > key ? &par->lft: &par->rgt;
147
    }
145
    }
148
 
146
 
149
    /*
147
    /*
150
     * Initialize new node.
148
     * Initialize new node.
151
     */
149
     */
152
    newnode->key = key;
150
    newnode->key = key;
153
    newnode->lft = NULL;
151
    newnode->lft = NULL;
154
    newnode->rgt = NULL;
152
    newnode->rgt = NULL;
155
    newnode->par = gpa;
153
    newnode->par = gpa;
156
    newnode->balance = 0;
154
    newnode->balance = 0;
157
 
155
 
158
    /*
156
    /*
159
     * Insert first node into the empty tree.
157
     * Insert first node into the empty tree.
160
     */
158
     */
161
    if (t->root == NULL) {
159
    if (t->root == NULL) {
162
        *dpc = newnode;
160
        *dpc = newnode;
163
        return;
161
        return;
164
    }
162
    }
165
 
163
 
166
    /*
164
    /*
167
     * Insert new node into previously found leaf place.
165
     * Insert new node into previously found leaf place.
168
     */
166
     */
169
    *dpc = newnode;
167
    *dpc = newnode;
170
 
168
 
171
    /*
169
    /*
172
     * If the tree contains one node - end.
170
     * If the tree contains one node - end.
173
     */
171
     */
174
    if (top == NULL)
172
    if (top == NULL)
175
        return;
173
        return;
176
 
174
 
177
    /*
175
    /*
178
     * Store pointer of top's father which points to the node with
176
     * Store pointer of top's father which points to the node with
179
     * potentially broken balance (top).
177
     * potentially broken balance (top).
180
     */
178
     */
181
    if (top->par == NULL) {
179
    if (top->par == NULL) {
182
        dpc = &t->root;
180
        dpc = &t->root;
183
    } else {
181
    } else {
184
        if (top->par->lft == top)
182
        if (top->par->lft == top)
185
            dpc = &top->par->lft;
183
            dpc = &top->par->lft;
186
        else
184
        else
187
            dpc = &top->par->rgt;
185
            dpc = &top->par->rgt;
188
    }
186
    }
189
 
187
 
190
    /*
188
    /*
191
     * Repair all balances on the way from top node to the newly inserted
189
     * Repair all balances on the way from top node to the newly inserted
192
     * node.
190
     * node.
193
     */
191
     */
194
    par = top;
192
    par = top;
195
    while (par != newnode) {
193
    while (par != newnode) {
196
        if (par->key > key) {
194
        if (par->key > key) {
197
            par->balance--;
195
            par->balance--;
198
            par = par->lft;
196
            par = par->lft;
199
        } else {
197
        } else {
200
            par->balance++;
198
            par->balance++;
201
            par = par->rgt;
199
            par = par->rgt;
202
        }
200
        }
203
    }
201
    }
204
   
202
   
205
    /*
203
    /*
206
     * To balance the tree, we must check and balance top node.
204
     * To balance the tree, we must check and balance top node.
207
     */
205
     */
208
    if (top->balance == -2) {
206
    if (top->balance == -2) {
209
        par = top->lft;
207
        par = top->lft;
210
        if (par->balance == -1) {
208
        if (par->balance == -1) {
211
            /*
209
            /*
212
             * LL rotation.
210
             * LL rotation.
213
             */
211
             */
214
            top->lft = par->rgt;
212
            top->lft = par->rgt;
215
            if (top->lft != NULL)
213
            if (top->lft != NULL)
216
                top->lft->par = top;
214
                top->lft->par = top;
217
            par->par = top->par;
215
            par->par = top->par;
218
            top->par = par;
216
            top->par = par;
219
            par->rgt = top;
217
            par->rgt = top;
220
            par->balance = 0;
218
            par->balance = 0;
221
            top->balance = 0;
219
            top->balance = 0;
222
            *dpc = par;
220
            *dpc = par;
223
        } else {
221
        } else {
224
            /*
222
            /*
225
             * LR rotation.
223
             * LR rotation.
226
             */
224
             */
227
            ASSERT(par->balance == 1);
225
            ASSERT(par->balance == 1);
228
           
226
           
229
            gpa = par->rgt;
227
            gpa = par->rgt;
230
            par->rgt = gpa->lft;
228
            par->rgt = gpa->lft;
231
            if (gpa->lft != NULL)
229
            if (gpa->lft != NULL)
232
                gpa->lft->par = par;
230
                gpa->lft->par = par;
233
            gpa->lft = par;
231
            gpa->lft = par;
234
            par->par = gpa;
232
            par->par = gpa;
235
            top->lft = gpa->rgt;
233
            top->lft = gpa->rgt;
236
            if (gpa->rgt != NULL)
234
            if (gpa->rgt != NULL)
237
                gpa->rgt->par = top;
235
                gpa->rgt->par = top;
238
            gpa->rgt = top;
236
            gpa->rgt = top;
239
            gpa->par = top->par;
237
            gpa->par = top->par;
240
            top->par = gpa;
238
            top->par = gpa;
241
           
239
           
242
            if (gpa->balance == -1) {
240
            if (gpa->balance == -1) {
243
                par->balance = 0;
241
                par->balance = 0;
244
                top->balance = 1;
242
                top->balance = 1;
245
            } else if (gpa->balance == 0) {
243
            } else if (gpa->balance == 0) {
246
                par->balance = 0;
244
                par->balance = 0;
247
                top->balance = 0;
245
                top->balance = 0;
248
            } else {
246
            } else {
249
                par->balance = -1;
247
                par->balance = -1;
250
                top->balance = 0;
248
                top->balance = 0;
251
            }
249
            }
252
            gpa->balance = 0;
250
            gpa->balance = 0;
253
            *dpc = gpa;
251
            *dpc = gpa;
254
        }
252
        }
255
    } else if (top->balance == 2) {
253
    } else if (top->balance == 2) {
256
        par = top->rgt;
254
        par = top->rgt;
257
        if (par->balance == 1) {
255
        if (par->balance == 1) {
258
            /*
256
            /*
259
             * RR rotation.
257
             * RR rotation.
260
             */
258
             */
261
            top->rgt = par->lft;
259
            top->rgt = par->lft;
262
            if (top->rgt != NULL)
260
            if (top->rgt != NULL)
263
                top->rgt->par = top;
261
                top->rgt->par = top;
264
            par->par = top->par;
262
            par->par = top->par;
265
            top->par = par;
263
            top->par = par;
266
            par->lft = top;
264
            par->lft = top;
267
            par->balance = 0;
265
            par->balance = 0;
268
            top->balance = 0;
266
            top->balance = 0;
269
            *dpc = par;
267
            *dpc = par;
270
        } else {
268
        } else {
271
            /*
269
            /*
272
             * RL rotation.
270
             * RL rotation.
273
             */
271
             */
274
            ASSERT(par->balance == -1);
272
            ASSERT(par->balance == -1);
275
           
273
           
276
            gpa = par->lft;
274
            gpa = par->lft;
277
            par->lft = gpa->rgt;
275
            par->lft = gpa->rgt;
278
            if (gpa->rgt != NULL)
276
            if (gpa->rgt != NULL)
279
                gpa->rgt->par = par;
277
                gpa->rgt->par = par;
280
            gpa->rgt = par;
278
            gpa->rgt = par;
281
            par->par = gpa;
279
            par->par = gpa;
282
            top->rgt = gpa->lft;
280
            top->rgt = gpa->lft;
283
            if (gpa->lft != NULL)
281
            if (gpa->lft != NULL)
284
                gpa->lft->par = top;
282
                gpa->lft->par = top;
285
            gpa->lft = top;
283
            gpa->lft = top;
286
            gpa->par = top->par;
284
            gpa->par = top->par;
287
            top->par = gpa;
285
            top->par = gpa;
288
 
286
 
289
            if (gpa->balance == 1) {
287
            if (gpa->balance == 1) {
290
                par->balance = 0;
288
                par->balance = 0;
291
                top->balance = -1;
289
                top->balance = -1;
292
            } else if (gpa->balance == 0) {
290
            } else if (gpa->balance == 0) {
293
                par->balance = 0;
291
                par->balance = 0;
294
                top->balance = 0;
292
                top->balance = 0;
295
            } else {
293
            } else {
296
                par->balance = 1;
294
                par->balance = 1;
297
                top->balance = 0;
295
                top->balance = 0;
298
            }
296
            }
299
            gpa->balance = 0;
297
            gpa->balance = 0;
300
            *dpc = gpa;
298
            *dpc = gpa;
301
        }
299
        }
302
    } else {
300
    } else {
303
        /*
301
        /*
304
         * Balance is not broken, insertion is finised.
302
         * Balance is not broken, insertion is finised.
305
         */
303
         */
306
        return;
304
        return;
307
    }
305
    }
308
 
306
 
309
}
307
}
310
 
308
 
311
/** Repair the tree after reparenting node u.
309
/** Repair the tree after reparenting node u.
312
 *
310
 *
313
 * If node u has no parent, mark it as the root of the whole tree. Otherwise
311
 * If node u has no parent, mark it as the root of the whole tree. Otherwise
314
 * node v represents stale address of one of the children of node u's parent.
312
 * node v represents stale address of one of the children of node u's parent.
315
 * Replace v with w as node u parent's child (for most uses, u and w will be the
313
 * Replace v with w as node u parent's child (for most uses, u and w will be the
316
 * same).
314
 * same).
317
 *
315
 *
318
 * @param t AVL tree.
316
 * @param t AVL tree.
319
 * @param u Node whose new parent has a stale child pointer.
317
 * @param u Node whose new parent has a stale child pointer.
320
 * @param v Stale child of node u's new parent.
318
 * @param v Stale child of node u's new parent.
321
 * @param w New child of node u's new parent.
319
 * @param w New child of node u's new parent.
322
 * @param dir   If not NULL, address of the variable where to store information
320
 * @param dir   If not NULL, address of the variable where to store information
323
 *      about whether w replaced v in the left or the right subtree of
321
 *      about whether w replaced v in the left or the right subtree of
324
 *      u's new parent.
322
 *      u's new parent.
325
 * @param ro    Read only operation; do not modify any tree pointers. This is
323
 * @param ro    Read only operation; do not modify any tree pointers. This is
326
 *      useful for tracking direction via the dir pointer.
324
 *      useful for tracking direction via the dir pointer.
327
 *
325
 *
328
 * @return  Zero if w became the new root of the tree, otherwise return
326
 * @return  Zero if w became the new root of the tree, otherwise return
329
 *      non-zero.
327
 *      non-zero.
330
 */
328
 */
331
static int
329
static int
332
repair(avltree_t *t, avltree_node_t *u, avltree_node_t *v, avltree_node_t *w,
330
repair(avltree_t *t, avltree_node_t *u, avltree_node_t *v, avltree_node_t *w,
333
    int *dir, int ro)
331
    int *dir, int ro)
334
{
332
{
335
    if (u->par == NULL) {
333
    if (u->par == NULL) {
336
        if (!ro)
334
        if (!ro)
337
            t->root = w;   
335
            t->root = w;   
338
        return 0;
336
        return 0;
339
    } else {   
337
    } else {   
340
        if (u->par->lft == v) {
338
        if (u->par->lft == v) {
341
            if (!ro)
339
            if (!ro)
342
                u->par->lft = w;
340
                u->par->lft = w;
343
            if (dir)
341
            if (dir)
344
                *dir = LEFT;
342
                *dir = LEFT;
345
        } else {
343
        } else {
346
            ASSERT(u->par->rgt == v);
344
            ASSERT(u->par->rgt == v);
347
            if (!ro)
345
            if (!ro)
348
                u->par->rgt = w;
346
                u->par->rgt = w;
349
            if (dir)
347
            if (dir)
350
                *dir = RIGHT;
348
                *dir = RIGHT;
351
        }
349
        }
352
    }
350
    }
353
    return 1;
351
    return 1;
354
}
352
}
355
 
353
 
356
#define REBALANCE(DIR1, DIR2, SIGN)     \
354
#define REBALANCE(DIR1, DIR2, SIGN)     \
357
    if (cur->balance == -1 * SIGN) {    \
355
    if (cur->balance == -1 * SIGN) {    \
358
        par->balance = 0;       \
356
        par->balance = 0;       \
359
        gpa->balance = 1 * SIGN;    \
357
        gpa->balance = 1 * SIGN;    \
360
        if (gpa->DIR1)          \
358
        if (gpa->DIR1)          \
361
            gpa->DIR1->par = gpa;   \
359
            gpa->DIR1->par = gpa;   \
362
        par->DIR2->par = par;       \
360
        par->DIR2->par = par;       \
363
    } else if (cur->balance == 0) {     \
361
    } else if (cur->balance == 0) {     \
364
        par->balance = 0;       \
362
        par->balance = 0;       \
365
        gpa->balance = 0;       \
363
        gpa->balance = 0;       \
366
        if (gpa->DIR1)          \
364
        if (gpa->DIR1)          \
367
            gpa->DIR1->par = gpa;   \
365
            gpa->DIR1->par = gpa;   \
368
        if (par->DIR2)          \
366
        if (par->DIR2)          \
369
            par->DIR2->par = par;   \
367
            par->DIR2->par = par;   \
370
    } else {                \
368
    } else {                \
371
        par->balance = -1 * SIGN;   \
369
        par->balance = -1 * SIGN;   \
372
        gpa->balance = 0;       \
370
        gpa->balance = 0;       \
373
        if (par->DIR2)          \
371
        if (par->DIR2)          \
374
            par->DIR2->par = par;   \
372
            par->DIR2->par = par;   \
375
        gpa->DIR1->par = gpa;       \
373
        gpa->DIR1->par = gpa;       \
376
    }                   \
374
    }                   \
377
    cur->balance = 0;
375
    cur->balance = 0;
378
 
376
 
379
#define REBALANCE_LR()      REBALANCE(lft, rgt, 1)
377
#define REBALANCE_LR()      REBALANCE(lft, rgt, 1)
380
#define REBALANCE_RL()      REBALANCE(rgt, lft, -1)
378
#define REBALANCE_RL()      REBALANCE(rgt, lft, -1)
381
 
379
 
382
/** Delete a node from the AVL tree.
380
/** Delete a node from the AVL tree.
383
 *
381
 *
384
 * Because multiple identical keys are allowed, the parent pointers are
382
 * Because multiple identical keys are allowed, the parent pointers are
385
 * essential during deletion.
383
 * essential during deletion.
386
 *
384
 *
387
 * @param t AVL tree structure.
385
 * @param t AVL tree structure.
388
 * @param node Address of the node which will be deleted.
386
 * @param node Address of the node which will be deleted.
389
 */
387
 */
390
void avltree_delete(avltree_t *t, avltree_node_t *node)
388
void avltree_delete(avltree_t *t, avltree_node_t *node)
391
{
389
{
392
    avltree_node_t *cur;
390
    avltree_node_t *cur;
393
    avltree_node_t *par;
391
    avltree_node_t *par;
394
    avltree_node_t *gpa;
392
    avltree_node_t *gpa;
395
    int dir;
393
    int dir;
396
 
394
 
397
    ASSERT(t);
395
    ASSERT(t);
398
    ASSERT(node);
396
    ASSERT(node);
399
   
397
   
400
    if (node->lft == NULL) {
398
    if (node->lft == NULL) {
401
        if (node->rgt) {
399
        if (node->rgt) {
402
            /*
400
            /*
403
             * Replace the node with its only right son.
401
             * Replace the node with its only right son.
404
             *
402
             *
405
             * Balance of the right son will be repaired in the
403
             * Balance of the right son will be repaired in the
406
             * balancing cycle.
404
             * balancing cycle.
407
             */
405
             */
408
            cur = node->rgt;
406
            cur = node->rgt;
409
            cur->par = node->par;
407
            cur->par = node->par;
410
            gpa = cur;
408
            gpa = cur;
411
            dir = RIGHT;
409
            dir = RIGHT;
412
            cur->balance = node->balance;
410
            cur->balance = node->balance;
413
        } else {
411
        } else {
414
            if (node->par == NULL) {
412
            if (node->par == NULL) {
415
                /*
413
                /*
416
                 * The tree has only one node - it will become
414
                 * The tree has only one node - it will become
417
                 * an empty tree and the balancing can end.
415
                 * an empty tree and the balancing can end.
418
                 */
416
                 */
419
                t->root = NULL;
417
                t->root = NULL;
420
                return;
418
                return;
421
            }
419
            }
422
            /*
420
            /*
423
             * The node has no child, it will be deleted with no
421
             * The node has no child, it will be deleted with no
424
             * substitution.
422
             * substitution.
425
             */
423
             */
426
            gpa = node->par;
424
            gpa = node->par;
427
            cur = NULL;
425
            cur = NULL;
428
            dir = (gpa->lft == node) ? LEFT: RIGHT;
426
            dir = (gpa->lft == node) ? LEFT: RIGHT;
429
        }
427
        }
430
    } else {
428
    } else {
431
        /*
429
        /*
432
         * The node has the left son. Find a node with the smallest key
430
         * The node has the left son. Find a node with the smallest key
433
         * in the left subtree and replace the deleted node with that
431
         * in the left subtree and replace the deleted node with that
434
         * node.
432
         * node.
435
         */
433
         */
436
        for (cur = node->lft; cur->rgt != NULL; cur = cur->rgt)
434
        for (cur = node->lft; cur->rgt != NULL; cur = cur->rgt)
437
            ;
435
            ;
438
 
436
 
439
        if (cur != node->lft) {
437
        if (cur != node->lft) {
440
            /*
438
            /*
441
             * The rightmost node of the deleted node's left subtree
439
             * The rightmost node of the deleted node's left subtree
442
             * was found. Replace the deleted node with this node.
440
             * was found. Replace the deleted node with this node.
443
             * Cutting off of the found node has two cases that
441
             * Cutting off of the found node has two cases that
444
             * depend on its left son.
442
             * depend on its left son.
445
             */
443
             */
446
            if (cur->lft) {
444
            if (cur->lft) {
447
                /*
445
                /*
448
                 * The found node has a left son.
446
                 * The found node has a left son.
449
                 */
447
                 */
450
                gpa = cur->lft;
448
                gpa = cur->lft;
451
                gpa->par = cur->par;
449
                gpa->par = cur->par;
452
                dir = LEFT;
450
                dir = LEFT;
453
                gpa->balance = cur->balance;
451
                gpa->balance = cur->balance;
454
            } else {
452
            } else {
455
                dir = RIGHT;
453
                dir = RIGHT;
456
                gpa = cur->par;
454
                gpa = cur->par;
457
            }
455
            }
458
            cur->par->rgt = cur->lft;
456
            cur->par->rgt = cur->lft;
459
            cur->lft = node->lft;
457
            cur->lft = node->lft;
460
            cur->lft->par = cur;
458
            cur->lft->par = cur;
461
        } else {
459
        } else {
462
            /*
460
            /*
463
             * The left son of the node hasn't got a right son. The
461
             * The left son of the node hasn't got a right son. The
464
             * left son will take the deleted node's place.
462
             * left son will take the deleted node's place.
465
             */
463
             */
466
            dir = LEFT;
464
            dir = LEFT;
467
            gpa = cur;
465
            gpa = cur;
468
        }
466
        }
469
        if (node->rgt)
467
        if (node->rgt)
470
            node->rgt->par = cur;
468
            node->rgt->par = cur;
471
        cur->rgt = node->rgt;
469
        cur->rgt = node->rgt;
472
        cur->balance = node->balance;
470
        cur->balance = node->balance;
473
        cur->par = node->par;
471
        cur->par = node->par;
474
    }
472
    }
475
   
473
   
476
    /*
474
    /*
477
     * Repair the parent node's pointer which pointed previously to the
475
     * Repair the parent node's pointer which pointed previously to the
478
     * deleted node.
476
     * deleted node.
479
     */
477
     */
480
    (void) repair(t, node, node, cur, NULL, false);
478
    (void) repair(t, node, node, cur, NULL, false);
481
   
479
   
482
    /*
480
    /*
483
     * Repair cycle which repairs balances of nodes on the way from from the
481
     * Repair cycle which repairs balances of nodes on the way from from the
484
     * cut-off node up to the root.
482
     * cut-off node up to the root.
485
     */
483
     */
486
    for (;;) {
484
    for (;;) {
487
        if (dir == LEFT) {
485
        if (dir == LEFT) {
488
            /*
486
            /*
489
             * Deletion was made in the left subtree.
487
             * Deletion was made in the left subtree.
490
             */
488
             */
491
            gpa->balance++;
489
            gpa->balance++;
492
            if (gpa->balance == 1) {
490
            if (gpa->balance == 1) {
493
                /*
491
                /*
494
                 * Stop balancing, the tree is balanced.
492
                 * Stop balancing, the tree is balanced.
495
                 */
493
                 */
496
                break;
494
                break;
497
            } else if (gpa->balance == 2) {
495
            } else if (gpa->balance == 2) {
498
                /*
496
                /*
499
                 * Bad balance, heights of left and right
497
                 * Bad balance, heights of left and right
500
                 * subtrees differ more than by one.
498
                 * subtrees differ more than by one.
501
                 */
499
                 */
502
                par = gpa->rgt;
500
                par = gpa->rgt;
503
 
501
 
504
                if (par->balance == -1) {
502
                if (par->balance == -1) {
505
                    /*
503
                    /*
506
                     * RL rotation.
504
                     * RL rotation.
507
                     */
505
                     */
508
                   
506
                   
509
                    cur = par->lft;
507
                    cur = par->lft;
510
                    par->lft = cur->rgt;
508
                    par->lft = cur->rgt;
511
                    cur->rgt = par;
509
                    cur->rgt = par;
512
                    gpa->rgt = cur->lft;
510
                    gpa->rgt = cur->lft;
513
                    cur->lft = gpa;
511
                    cur->lft = gpa;
514
                   
512
                   
515
                    /*
513
                    /*
516
                     * Repair balances and paternity of
514
                     * Repair balances and paternity of
517
                     * children, depending on the balance
515
                     * children, depending on the balance
518
                     * factor of the grand child (cur).
516
                     * factor of the grand child (cur).
519
                     */
517
                     */
520
                    REBALANCE_RL();
518
                    REBALANCE_RL();
521
                   
519
                   
522
                    /*
520
                    /*
523
                     * Repair paternity.
521
                     * Repair paternity.
524
                     */
522
                     */
525
                    cur->par = gpa->par;
523
                    cur->par = gpa->par;
526
                    gpa->par = cur;
524
                    gpa->par = cur;
527
                    par->par = cur;
525
                    par->par = cur;
528
 
526
 
529
                    if (!repair(t, cur, gpa, cur, &dir,
527
                    if (!repair(t, cur, gpa, cur, &dir,
530
                        false))
528
                        false))
531
                        break;
529
                        break;
532
                    gpa = cur->par;
530
                    gpa = cur->par;
533
                } else {
531
                } else {
534
                    /*
532
                    /*
535
                     * RR rotation.
533
                     * RR rotation.
536
                     */
534
                     */
537
                   
535
                   
538
                    gpa->rgt = par->lft;
536
                    gpa->rgt = par->lft;
539
                    if (par->lft)
537
                    if (par->lft)
540
                        par->lft->par = gpa;
538
                        par->lft->par = gpa;
541
                    par->lft = gpa;
539
                    par->lft = gpa;
542
                   
540
                   
543
                    /*
541
                    /*
544
                     * Repair paternity.
542
                     * Repair paternity.
545
                     */
543
                     */
546
                    par->par = gpa->par;
544
                    par->par = gpa->par;
547
                    gpa->par = par;
545
                    gpa->par = par;
548
                   
546
                   
549
                    if (par->balance == 0) {
547
                    if (par->balance == 0) {
550
                        /*
548
                        /*
551
                         * The right child of the
549
                         * The right child of the
552
                         * balanced node is balanced,
550
                         * balanced node is balanced,
553
                         * after RR rotation is done,
551
                         * after RR rotation is done,
554
                         * the whole tree will be
552
                         * the whole tree will be
555
                         * balanced.
553
                         * balanced.
556
                         */
554
                         */
557
                        par->balance = -1;
555
                        par->balance = -1;
558
                        gpa->balance = 1;
556
                        gpa->balance = 1;
559
 
557
 
560
                        (void) repair(t, par, gpa, par,
558
                        (void) repair(t, par, gpa, par,
561
                            NULL, false);
559
                            NULL, false);
562
                        break;
560
                        break;
563
                    } else {
561
                    } else {
564
                        par->balance = 0;
562
                        par->balance = 0;
565
                        gpa->balance = 0;
563
                        gpa->balance = 0;
566
                        if (!repair(t, par, gpa, par,
564
                        if (!repair(t, par, gpa, par,
567
                            &dir, false))
565
                            &dir, false))
568
                            break;
566
                            break;
569
                    }
567
                    }
570
                    gpa = par->par;
568
                    gpa = par->par;
571
                }
569
                }
572
            } else {
570
            } else {
573
                /*
571
                /*
574
                 * Repair the pointer which pointed to the
572
                 * Repair the pointer which pointed to the
575
                 * balanced node. If it was root then balancing
573
                 * balanced node. If it was root then balancing
576
                 * is finished else continue with the next
574
                 * is finished else continue with the next
577
                 * iteration (parent node).
575
                 * iteration (parent node).
578
                 */
576
                 */
579
                if (!repair(t, gpa, gpa, NULL, &dir, true))
577
                if (!repair(t, gpa, gpa, NULL, &dir, true))
580
                    break;
578
                    break;
581
                gpa = gpa->par;
579
                gpa = gpa->par;
582
            }
580
            }
583
        } else {
581
        } else {
584
            /*
582
            /*
585
             * Deletion was made in the right subtree.
583
             * Deletion was made in the right subtree.
586
             */
584
             */
587
            gpa->balance--;
585
            gpa->balance--;
588
            if (gpa->balance == -1) {
586
            if (gpa->balance == -1) {
589
                /*
587
                /*
590
                 * Stop balancing, the tree is balanced.
588
                 * Stop balancing, the tree is balanced.
591
                 */
589
                 */
592
                break;
590
                break;
593
            } else if (gpa->balance == -2) {
591
            } else if (gpa->balance == -2) {
594
                /*
592
                /*
595
                 * Bad balance, heights of left and right
593
                 * Bad balance, heights of left and right
596
                 * subtrees differ more than by one.
594
                 * subtrees differ more than by one.
597
                 */
595
                 */
598
                par = gpa->lft;
596
                par = gpa->lft;
599
               
597
               
600
                if (par->balance == 1) {
598
                if (par->balance == 1) {
601
                    /*
599
                    /*
602
                     * LR rotation.
600
                     * LR rotation.
603
                     */
601
                     */
604
                   
602
                   
605
                    cur = par->rgt;
603
                    cur = par->rgt;
606
                    par->rgt = cur->lft;
604
                    par->rgt = cur->lft;
607
                    cur->lft = par;
605
                    cur->lft = par;
608
                    gpa->lft = cur->rgt;
606
                    gpa->lft = cur->rgt;
609
                    cur->rgt = gpa;
607
                    cur->rgt = gpa;
610
                   
608
                   
611
                    /*
609
                    /*
612
                     * Repair balances and paternity of
610
                     * Repair balances and paternity of
613
                     * children, depending on the balance
611
                     * children, depending on the balance
614
                     * factor of the grand child (cur).
612
                     * factor of the grand child (cur).
615
                     */
613
                     */
616
                    REBALANCE_LR();
614
                    REBALANCE_LR();
617
 
615
 
618
                    /*
616
                    /*
619
                     * Repair paternity.
617
                     * Repair paternity.
620
                     */
618
                     */
621
                    cur->par = gpa->par;
619
                    cur->par = gpa->par;
622
                    gpa->par = cur;
620
                    gpa->par = cur;
623
                    par->par = cur;
621
                    par->par = cur;
624
 
622
 
625
                    if (!repair(t, cur, gpa, cur, &dir,
623
                    if (!repair(t, cur, gpa, cur, &dir,
626
                        false))
624
                        false))
627
                        break;
625
                        break;
628
                    gpa = cur->par;
626
                    gpa = cur->par;
629
                } else {
627
                } else {
630
                    /*
628
                    /*
631
                     * LL rotation.
629
                     * LL rotation.
632
                     */
630
                     */
633
 
631
 
634
                    gpa->lft = par->rgt;
632
                    gpa->lft = par->rgt;
635
                    if (par->rgt)
633
                    if (par->rgt)
636
                        par->rgt->par = gpa;
634
                        par->rgt->par = gpa;
637
                    par->rgt = gpa;
635
                    par->rgt = gpa;
638
                    /*
636
                    /*
639
                     * Repair paternity.
637
                     * Repair paternity.
640
                     */
638
                     */
641
                    par->par = gpa->par;
639
                    par->par = gpa->par;
642
                    gpa->par = par;
640
                    gpa->par = par;
643
                   
641
                   
644
                    if (par->balance == 0) {
642
                    if (par->balance == 0) {
645
                        /*
643
                        /*
646
                         * The left child of the
644
                         * The left child of the
647
                         * balanced node is balanced,
645
                         * balanced node is balanced,
648
                         * after LL rotation is done,
646
                         * after LL rotation is done,
649
                         * the whole tree will be
647
                         * the whole tree will be
650
                         * balanced.
648
                         * balanced.
651
                         */
649
                         */
652
                        par->balance = 1;
650
                        par->balance = 1;
653
                        gpa->balance = -1;
651
                        gpa->balance = -1;
654
                       
652
                       
655
                        (void) repair(t, par, gpa, par,
653
                        (void) repair(t, par, gpa, par,
656
                            NULL, false);
654
                            NULL, false);
657
                        break;
655
                        break;
658
                    } else {
656
                    } else {
659
                        par->balance = 0;
657
                        par->balance = 0;
660
                        gpa->balance = 0;
658
                        gpa->balance = 0;
661
                       
659
                       
662
                        if (!repair(t, par, gpa, par,
660
                        if (!repair(t, par, gpa, par,
663
                            &dir, false))
661
                            &dir, false))
664
                            break;
662
                            break;
665
                    }
663
                    }
666
                    gpa = par->par;
664
                    gpa = par->par;
667
                }
665
                }
668
            } else {
666
            } else {
669
                /*
667
                /*
670
                 * Repair the pointer which pointed to the
668
                 * Repair the pointer which pointed to the
671
                 * balanced node. If it was root then balancing
669
                 * balanced node. If it was root then balancing
672
                 * is finished. Otherwise continue with the next
670
                 * is finished. Otherwise continue with the next
673
                 * iteration (parent node).
671
                 * iteration (parent node).
674
                 */
672
                 */
675
                if (!repair(t, gpa, gpa, NULL, &dir, true))
673
                if (!repair(t, gpa, gpa, NULL, &dir, true))
676
                    break;
674
                    break;
677
                gpa = gpa->par;
675
                gpa = gpa->par;
678
            }
676
            }
679
        }
677
        }
680
    }
678
    }
681
}
679
}
682
 
680
 
683
 
681
 
684
/** Delete a node with the smallest key from the AVL tree.
682
/** Delete a node with the smallest key from the AVL tree.
685
 *
683
 *
686
 * @param t AVL tree structure.
684
 * @param t AVL tree structure.
687
 */
685
 */
688
bool avltree_delete_min(avltree_t *t)
686
bool avltree_delete_min(avltree_t *t)
689
{
687
{
690
    avltree_node_t *node;
688
    avltree_node_t *node;
691
   
689
   
692
    /*
690
    /*
693
     * Start searching for the smallest key in the tree starting in the root
691
     * Start searching for the smallest key in the tree starting in the root
694
     * node and continue in cycle to the leftmost node in the tree (which
692
     * node and continue in cycle to the leftmost node in the tree (which
695
     * must have the smallest key).
693
     * must have the smallest key).
696
     */
694
     */
697
     
695
     
698
    node = t->root;
696
    node = t->root;
699
    if (!node)
697
    if (!node)
700
        return false;
698
        return false;
701
   
699
   
702
    while (node->lft != NULL)
700
    while (node->lft != NULL)
703
        node = node->lft;
701
        node = node->lft;
704
   
702
   
705
    avltree_delete(t, node);
703
    avltree_delete(t, node);
706
 
704
 
707
    return true;
705
    return true;
708
}
706
}
-
 
707
 
-
 
708
static void _avltree_walk(avltree_node_t *node, avltree_walker_t walker)
-
 
709
{
-
 
710
    if (node->lft)
-
 
711
        _avltree_walk(node->lft, walker);
-
 
712
    walker(node);
-
 
713
    if (node->rgt)
-
 
714
        _avltree_walk(node->rgt, walker);
-
 
715
}
-
 
716
 
-
 
717
/** Walk the AVL tree and apply the walker function on each visited node.
-
 
718
 *
-
 
719
 * @param t     AVL tree to be walked.
-
 
720
 * @param walker    Walker function that will be called on each visited
-
 
721
 *          node.
-
 
722
 */
-
 
723
void avltree_walk(avltree_t *t, avltree_walker_t walker)
-
 
724
{
-
 
725
    _avltree_walk(t->root, walker);
-
 
726
}
709
 
727
 
710
/** @}
728
/** @}
711
 */
729
 */
712
 
730
 
713
 
731