3665760bca88b1f5f1b2f871f1ebb64d0863a862
1 #include <stdlib.h>
2 #include <assert.h>
4 #include "utils_avltree.h"
6 #define BALANCE(n) ((((n)->right == NULL) ? 0 : (n)->right->height) \
7 - (((n)->left == NULL) ? 0 : (n)->left->height))
9 /*
10 * private data types
11 */
12 struct avl_node_s
13 {
14 void *key;
15 void *value;
17 int height;
18 struct avl_node_s *left;
19 struct avl_node_s *right;
20 struct avl_node_s *parent;
21 };
22 typedef struct avl_node_s avl_node_t;
24 struct avl_tree_s
25 {
26 avl_node_t *root;
27 int (*compare) (const void *, const void *);
28 };
30 struct avl_iterator_s
31 {
32 avl_tree_t *tree;
33 avl_node_t *node;
34 };
36 /*
37 * private functions
38 */
39 static void free_node (avl_node_t *n)
40 {
41 if (n == NULL)
42 return;
44 if (n->left != NULL)
45 free_node (n->left);
46 if (n->right != NULL)
47 free_node (n->right);
49 free (n);
50 }
52 static avl_node_t *search (avl_tree_t *t, void *key)
53 {
54 avl_node_t *n;
55 int cmp;
57 n = t->root;
58 while (n != NULL)
59 {
60 cmp = t->compare (key, n->key);
61 if (cmp == 0)
62 return (n);
63 else if (cmp < 0)
64 n = n->left;
65 else
66 n = n->right;
67 }
69 return (NULL);
70 }
72 static void rebalance (avl_tree_t *t, avl_node_t *n)
73 {
74 int height_left;
75 int height_right;
76 int height_new;
77 int cmp;
79 while (n != NULL)
80 {
81 height_left = (n->left == NULL) ? 0 : n->left->height;
82 height_right = (n->right == NULL) ? 0 : n->right->height;
84 height_new = 1 + ((height_left > height_right) ? height_left : height_right);
86 if (height_new == n->height)
87 break;
89 n->height = height_new;
91 cmp = height_right - height_left;
92 if (cmp < -1)
93 {
94 avl_node_t *l;
95 avl_node_t *lr;
97 l = n->left;
98 lr = l->right;
100 l->right = n;
101 l->parent = n->parent;
102 n->parent = l;
103 n->left = lr;
105 if (lr != NULL)
106 lr->parent = n;
108 if (l->parent == NULL)
109 {
110 assert (t->root == n);
111 t->root = l;
112 }
113 else
114 {
115 assert ((l->parent->left == n) || (l->parent->right == n));
116 if (l->parent->left == n)
117 l->parent->left = l;
118 else
119 l->parent->right = l;
120 }
121 }
122 else if (cmp > 1)
123 {
124 avl_node_t *r;
125 avl_node_t *rl;
127 r = n->right;
128 rl = r->left;
130 r->left = n;
131 r->parent = n->parent;
132 n->parent = r;
133 n->right = rl;
135 if (rl != NULL)
136 rl->parent = n;
138 if (r->parent == NULL)
139 {
140 assert (t->root == n);
141 t->root = r;
142 }
143 else
144 {
145 assert ((r->parent->left == n) || (r->parent->right == n));
146 if (r->parent->left == n)
147 r->parent->left = r;
148 else
149 r->parent->right = r;
150 }
151 }
152 else
153 {
154 n = n->parent;
155 }
157 assert ((n == NULL) || (n->parent == NULL)
158 || (n->parent->left == n)
159 || (n->parent->right == n));
160 } /* while (n != NULL) */
161 } /* void rebalance */
163 static avl_iterator_t *avl_create_iterator (avl_tree_t *t, avl_node_t *n)
164 {
165 avl_iterator_t *iter;
167 iter = (avl_iterator_t *) malloc (sizeof (avl_iterator_t));
168 if (iter == NULL)
169 return (NULL);
171 iter->tree = t;
172 iter->node = n;
174 return (iter);
175 }
177 void *avl_node_next (avl_tree_t *t, avl_node_t *n)
178 {
179 avl_node_t *r; /* return node */
181 if (n == NULL)
182 {
183 return (NULL);
184 }
185 else if (n->right == NULL)
186 {
188 r = n->parent;
189 while (r != NULL)
190 {
191 /* stop if a bigger node is found */
192 if (t->compare (n, r) < 0) /* n < r */
193 break;
194 r = r->parent;
195 }
196 }
197 else
198 {
199 r = n->right;
200 while (r->left != NULL)
201 r = r->left;
202 }
204 return (r);
205 }
207 void *avl_node_prev (avl_tree_t *t, avl_node_t *n)
208 {
209 avl_node_t *r; /* return node */
211 if (n == NULL)
212 {
213 return (NULL);
214 }
215 else if (n->left == NULL)
216 {
218 r = n->parent;
219 while (r != NULL)
220 {
221 /* stop if a smaller node is found */
222 if (t->compare (n, r) > 0) /* n > r */
223 break;
224 r = r->parent;
225 }
226 }
227 else
228 {
229 r = n->left;
230 while (r->right != NULL)
231 r = r->right;
232 }
234 return (r);
235 }
237 static void *_remove (avl_tree_t *t, avl_node_t *n)
238 {
239 void *ret;
241 assert ((t != NULL) && (n != NULL));
243 ret = n->value;
245 if ((n->left == NULL) && (n->right == NULL))
246 {
247 /* Deleting a leave is easy */
248 if (n->parent == NULL)
249 {
250 assert (t->root == n);
251 t->root = NULL;
252 }
253 else
254 {
255 assert ((n->parent->left == n)
256 || (n->parent->right == n));
257 if (n->parent->left == n)
258 n->parent->left = NULL;
259 else
260 n->parent->right = NULL;
262 rebalance (t, n->parent);
263 }
265 free_node (n);
266 }
267 else
268 {
269 avl_node_t *r; /* replacement node */
270 if (BALANCE (n) < 0)
271 {
272 assert (n->left != NULL);
273 r = avl_node_prev (t, n);
274 }
275 else
276 {
277 assert (n->right != NULL);
278 r = avl_node_next (t, n);
279 }
280 n->key = r->key;
281 n->value = r->value;
283 _remove (t, r);
284 }
286 return (ret);
287 } /* void *_remove */
289 /*
290 * public functions
291 */
292 avl_tree_t *avl_create (int (*compare) (const void *, const void *))
293 {
294 avl_tree_t *t;
296 if ((t = (avl_tree_t *) malloc (sizeof (avl_tree_t))) == NULL)
297 return (NULL);
299 t->root = NULL;
300 t->compare = compare;
302 return (t);
303 }
305 void avl_destroy (avl_tree_t *t)
306 {
307 free_node (t->root);
308 free (t);
309 }
311 int avl_insert (avl_tree_t *t, void *key, void *value)
312 {
313 avl_node_t *new;
314 avl_node_t *nptr;
315 int cmp;
317 if ((new = (avl_node_t *) malloc (sizeof (avl_node_t))) == NULL)
318 return (-1);
320 new->key = key;
321 new->value = value;
322 new->height = 1;
323 new->left = NULL;
324 new->right = NULL;
326 if (t->root == NULL)
327 {
328 new->parent = NULL;
329 t->root = new;
330 return (0);
331 }
333 nptr = t->root;
334 while (42)
335 {
336 cmp = t->compare (nptr->key, new->key);
337 if (cmp == 0)
338 {
339 free_node (new);
340 return (-1);
341 }
342 else if (cmp < 0)
343 {
344 /* nptr < new */
345 if (nptr->right == NULL)
346 {
347 nptr->right = new;
348 new->parent = nptr;
349 nptr = NULL;
350 break;
351 }
352 else
353 {
354 nptr = nptr->right;
355 }
356 }
357 else /* if (cmp > 0) */
358 {
359 /* nptr > new */
360 if (nptr->left == NULL)
361 {
362 nptr->left = new;
363 new->parent = nptr;
364 nptr = NULL;
365 break;
366 }
367 else
368 {
369 nptr = nptr->left;
370 }
371 }
372 } /* while (42) */
374 assert ((new->parent != NULL)
375 && ((new->parent->left == new)
376 || (new->parent->right == new)));
378 return (0);
379 } /* int avl_insert */
381 void *avl_remove (avl_tree_t *t, void *key)
382 {
383 avl_node_t *n;
385 assert (t != NULL);
387 n = search (t, key);
388 if (n == NULL)
389 return (NULL);
391 return (_remove (t, n));
392 } /* void *avl_remove */
394 void *avl_get (avl_tree_t *t, void *key)
395 {
396 avl_node_t *n;
398 n = search (t, key);
399 if (n == NULL)
400 return (NULL);
402 return (n->value);
403 }
405 avl_iterator_t *avl_get_iterator (avl_tree_t *t)
406 {
407 avl_node_t *n;
409 if (t == NULL)
410 return (NULL);
412 for (n = t->root; n != NULL; n = n->left)
413 if (n->left == NULL)
414 break;
416 return (avl_create_iterator (t, n));
417 } /* avl_iterator_t *avl_get_iterator */
419 void *avl_iterator_next (avl_iterator_t *iter)
420 {
421 avl_node_t *n;
423 if ((iter == NULL) || (iter->node == NULL))
424 return (NULL);
426 n = avl_node_next (iter->tree, iter->node);
428 if (n == NULL)
429 return (NULL);
431 iter->node = n;
432 return (n);
434 }
436 void *avl_iterator_prev (avl_iterator_t *iter)
437 {
438 avl_node_t *n;
440 if ((iter == NULL) || (iter->node == NULL))
441 return (NULL);
443 n = avl_node_prev (iter->tree, iter->node);
445 if (n == NULL)
446 return (NULL);
448 iter->node = n;
449 return (n);
451 }
453 void avl_iterator_destroy (avl_iterator_t *iter)
454 {
455 free (iter);
456 }