OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
avl.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  avl.c - Source code for the AVL-tree library.
4 
5  Copyright (C) 1998 Michael H. Buselli <cosine@cosine.org>
6  Copyright (C) 2000-2002 Wessel Dankers <wsl@nl.linux.org>
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 
22  Augmented AVL-tree. Original by Michael H. Buselli <cosine@cosine.org>.
23 
24  Modified by Wessel Dankers <wsl@nl.linux.org> to add a bunch of bloat to
25  the sourcecode, change the interface and squash a few bugs.
26  Mail him if you find new bugs.
27 
28 *****************************************************************************/
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include "avl.h"
34 
35 static void avl_rebalance(avl_tree_t *, avl_node_t *);
36 
37 #ifdef AVL_COUNT
38 #define NODE_COUNT(n) ((n) ? (n)->count : 0)
39 #define L_COUNT(n) (NODE_COUNT((n)->left))
40 #define R_COUNT(n) (NODE_COUNT((n)->right))
41 #define CALC_COUNT(n) (L_COUNT(n) + R_COUNT(n) + 1)
42 #endif
43 
44 #ifdef AVL_DEPTH
45 #define NODE_DEPTH(n) ((n) ? (n)->depth : 0)
46 #define L_DEPTH(n) (NODE_DEPTH((n)->left))
47 #define R_DEPTH(n) (NODE_DEPTH((n)->right))
48 #define CALC_DEPTH(n) ((L_DEPTH(n)>R_DEPTH(n)?L_DEPTH(n):R_DEPTH(n)) + 1)
49 #endif
50 
51 #ifndef AVL_DEPTH
52 /* Also known as ffs() (from BSD) */
53 static int lg(unsigned int u) {
54  int r = 1;
55  if(!u) return 0;
56  if(u & 0xffff0000) { u >>= 16; r += 16; }
57  if(u & 0x0000ff00) { u >>= 8; r += 8; }
58  if(u & 0x000000f0) { u >>= 4; r += 4; }
59  if(u & 0x0000000c) { u >>= 2; r += 2; }
60  if(u & 0x00000002) r++;
61  return r;
62 }
63 #endif
64 
65 static int avl_check_balance(avl_node_t *avlnode) {
66 #ifdef AVL_DEPTH
67  int d;
68  d = R_DEPTH(avlnode) - L_DEPTH(avlnode);
69  return d<-1?-1:d>1?1:0;
70 #else
71 /* int d;
72  * d = lg(R_COUNT(avlnode)) - lg(L_COUNT(avlnode));
73  * d = d<-1?-1:d>1?1:0;
74  */
75 #ifdef AVL_COUNT
76  int pl, r;
77 
78  pl = lg(L_COUNT(avlnode));
79  r = R_COUNT(avlnode);
80 
81  if(r>>pl+1)
82  return 1;
83  if(pl<2 || r>>pl-2)
84  return 0;
85  return -1;
86 #else
87 #error No balancing possible.
88 #endif
89 #endif
90 }
91 
92 #ifdef AVL_COUNT
93 unsigned int avl_count(const avl_tree_t *avltree) {
94  return NODE_COUNT(avltree->top);
95 }
96 
97 avl_node_t *avl_at(const avl_tree_t *avltree, unsigned int index) {
98  avl_node_t *avlnode;
99  unsigned int c;
100 
101  avlnode = avltree->top;
102 
103  while(avlnode) {
104  c = L_COUNT(avlnode);
105 
106  if(index < c) {
107  avlnode = avlnode->left;
108  } else if(index > c) {
109  avlnode = avlnode->right;
110  index -= c+1;
111  } else {
112  return avlnode;
113  }
114  }
115  return NULL;
116 }
117 
118 unsigned int avl_index(const avl_node_t *avlnode) {
119  avl_node_t *next;
120  unsigned int c;
121 
122  c = L_COUNT(avlnode);
123 
124  while((next = avlnode->parent)) {
125  if(avlnode == next->right)
126  c += L_COUNT(next) + 1;
127  avlnode = next;
128  }
129 
130  return c;
131 }
132 #endif
133 
134 int avl_search_closest(const avl_tree_t *avltree, const void *item, avl_node_t **avlnode) {
135  avl_node_t *node;
136  avl_compare_t cmp;
137  int c;
138 
139  if(!avlnode)
140  avlnode = &node;
141 
142  node = avltree->top;
143 
144  if(!node)
145  return *avlnode = NULL, 0;
146 
147  cmp = avltree->cmp;
148 
149  for(;;) {
150  c = cmp(item, node->item);
151 
152  if(c < 0) {
153  if(node->left)
154  node = node->left;
155  else
156  return *avlnode = node, -1;
157  } else if(c > 0) {
158  if(node->right)
159  node = node->right;
160  else
161  return *avlnode = node, 1;
162  } else {
163  return *avlnode = node, 0;
164  }
165  }
166 }
167 
168 /*
169  * avl_search:
170  * Return a pointer to a node with the given item in the tree.
171  * If no such item is in the tree, then NULL is returned.
172  */
173 avl_node_t *avl_search(const avl_tree_t *avltree, const void *item) {
174  avl_node_t *node;
175  return avl_search_closest(avltree, item, &node) ? NULL : node;
176 }
177 
179  if(rc) {
180  rc->head = NULL;
181  rc->tail = NULL;
182  rc->top = NULL;
183  rc->cmp = cmp;
184  rc->freeitem = freeitem;
185  }
186  return rc;
187 }
188 
190  return avl_init_tree((avl_tree_t*)malloc(sizeof(avl_tree_t)), cmp, freeitem);
191 }
192 
193 void avl_clear_tree(avl_tree_t *avltree) {
194  avltree->top = avltree->head = avltree->tail = NULL;
195 }
196 
197 void avl_free_nodes(avl_tree_t *avltree) {
198  avl_node_t *node, *next;
199  avl_freeitem_t freeitem;
200 
201  freeitem = avltree->freeitem;
202 
203  for(node = avltree->head; node; node = next) {
204  next = node->next;
205  if(freeitem)
206  freeitem(node->item);
207  free(node);
208  }
209  return avl_clear_tree(avltree);
210 }
211 
212 /*
213  * avl_free_tree:
214  * Free all memory used by this tree. If freeitem is not NULL, then
215  * it is assumed to be a destructor for the items referenced in the avl_
216  * tree, and they are deleted as well.
217  */
218 void avl_free_tree(avl_tree_t *avltree) {
219  avl_free_nodes(avltree);
220  free(avltree);
221 }
222 
223 static void avl_clear_node(avl_node_t *newnode) {
224  newnode->left = newnode->right = NULL;
225  #ifdef AVL_COUNT
226  newnode->count = 1;
227  #endif
228  #ifdef AVL_DEPTH
229  newnode->depth = 1;
230  #endif
231 }
232 
233 avl_node_t *avl_init_node(avl_node_t *newnode, void *item) {
234  if(newnode) {
235  avl_clear_node(newnode);
236  newnode->item = item;
237  }
238  return newnode;
239 }
240 
242  avl_clear_node(newnode);
243  newnode->prev = newnode->next = newnode->parent = NULL;
244  avltree->head = avltree->tail = avltree->top = newnode;
245  return newnode;
246 }
247 
249  if(!node)
250  return avltree->tail
251  ? avl_insert_after(avltree, avltree->tail, newnode)
252  : avl_insert_top(avltree, newnode);
253 
254  if(node->left)
255  return avl_insert_after(avltree, node->prev, newnode);
256 
257  avl_clear_node(newnode);
258 
259  newnode->next = node;
260  newnode->parent = node;
261 
262  newnode->prev = node->prev;
263  if(node->prev)
264  node->prev->next = newnode;
265  else
266  avltree->head = newnode;
267  node->prev = newnode;
268 
269  node->left = newnode;
270  avl_rebalance(avltree, node);
271  return newnode;
272 }
273 
275  if(!node)
276  return avltree->head
277  ? avl_insert_before(avltree, avltree->head, newnode)
278  : avl_insert_top(avltree, newnode);
279 
280  if(node->right)
281  return avl_insert_before(avltree, node->next, newnode);
282 
283  avl_clear_node(newnode);
284 
285  newnode->prev = node;
286  newnode->parent = node;
287 
288  newnode->next = node->next;
289  if(node->next)
290  node->next->prev = newnode;
291  else
292  avltree->tail = newnode;
293  node->next = newnode;
294 
295  node->right = newnode;
296  avl_rebalance(avltree, node);
297  return newnode;
298 }
299 
301  avl_node_t *node;
302 
303  if(!avltree->top)
304  return avl_insert_top(avltree, newnode);
305 
306  switch(avl_search_closest(avltree, newnode->item, &node)) {
307  case -1:
308  return avl_insert_before(avltree, node, newnode);
309  case 1:
310  return avl_insert_after(avltree, node, newnode);
311  }
312 
313  return NULL;
314 }
315 
316 /*
317  * avl_insert:
318  * Create a new node and insert an item there.
319  * Returns the new node on success or NULL if no memory could be allocated.
320  */
321 avl_node_t *avl_insert(avl_tree_t *avltree, void *item) {
322  avl_node_t *newnode;
323 
324  newnode = avl_init_node((avl_node_t*)malloc(sizeof(avl_node_t)), item);
325  if(newnode) {
326  if(avl_insert_node(avltree, newnode))
327  return newnode;
328  free(newnode);
329  errno = EEXIST;
330  }
331  return NULL;
332 }
333 
334 /*
335  * avl_unlink_node:
336  * Removes the given node. Does not delete the item at that node.
337  * The item of the node may be freed before calling avl_unlink_node.
338  * (In other words, it is not referenced by this function.)
339  */
340 void avl_unlink_node(avl_tree_t *avltree, avl_node_t *avlnode) {
341  avl_node_t *parent;
342  avl_node_t **superparent;
343  avl_node_t *subst, *left, *right;
344  avl_node_t *balnode;
345 
346  if(avlnode->prev)
347  avlnode->prev->next = avlnode->next;
348  else
349  avltree->head = avlnode->next;
350 
351  if(avlnode->next)
352  avlnode->next->prev = avlnode->prev;
353  else
354  avltree->tail = avlnode->prev;
355 
356  parent = avlnode->parent;
357 
358  superparent = parent
359  ? avlnode == parent->left ? &parent->left : &parent->right
360  : &avltree->top;
361 
362  left = avlnode->left;
363  right = avlnode->right;
364  if(!left) {
365  *superparent = right;
366  if(right)
367  right->parent = parent;
368  balnode = parent;
369  } else if(!right) {
370  *superparent = left;
371  left->parent = parent;
372  balnode = parent;
373  } else {
374  subst = avlnode->prev;
375  if(subst == left) {
376  balnode = subst;
377  } else {
378  balnode = subst->parent;
379  balnode->right = subst->left;
380  if(balnode->right)
381  balnode->right->parent = balnode;
382  subst->left = left;
383  left->parent = subst;
384  }
385  subst->right = right;
386  subst->parent = parent;
387  right->parent = subst;
388  *superparent = subst;
389  }
390 
391  avl_rebalance(avltree, balnode);
392 }
393 
394 void *avl_delete_node(avl_tree_t *avltree, avl_node_t *avlnode) {
395  void *item = NULL;
396  if(avlnode) {
397  item = avlnode->item;
398  avl_unlink_node(avltree, avlnode);
399  if(avltree->freeitem)
400  avltree->freeitem(item);
401  free(avlnode);
402  }
403  return item;
404 }
405 
406 void *avl_delete(avl_tree_t *avltree, const void *item) {
407  return avl_delete_node(avltree, avl_search(avltree, item));
408 }
409 
411  avl_node_t *oldnode = NULL, *node;
412 
413  if(!avltree || !newnode)
414  return NULL;
415 
416  node = newnode->prev;
417  if(node) {
418  oldnode = node->next;
419  node->next = newnode;
420  } else {
421  avltree->head = newnode;
422  }
423 
424  node = newnode->next;
425  if(node) {
426  oldnode = node->prev;
427  node->prev = newnode;
428  } else {
429  avltree->tail = newnode;
430  }
431 
432  node = newnode->parent;
433  if(node) {
434  if(node->left == oldnode)
435  node->left = newnode;
436  else
437  node->right = newnode;
438  } else {
439  oldnode = avltree->top;
440  avltree->top = newnode;
441  }
442 
443  return oldnode;
444 }
445 
446 /*
447  * avl_rebalance:
448  * Rebalances the tree if one side becomes too heavy. This function
449  * assumes that both subtrees are AVL-trees with consistant data. The
450  * function has the additional side effect of recalculating the count of
451  * the tree at this node. It should be noted that at the return of this
452  * function, if a rebalance takes place, the top of this subtree is no
453  * longer going to be the same node.
454  */
455 void avl_rebalance(avl_tree_t *avltree, avl_node_t *avlnode) {
456  avl_node_t *child;
457  avl_node_t *gchild;
458  avl_node_t *parent;
459  avl_node_t **superparent;
460 
461  parent = avlnode;
462 
463  while(avlnode) {
464  parent = avlnode->parent;
465 
466  superparent = parent
467  ? avlnode == parent->left ? &parent->left : &parent->right
468  : &avltree->top;
469 
470  switch(avl_check_balance(avlnode)) {
471  case -1:
472  child = avlnode->left;
473  #ifdef AVL_DEPTH
474  if(L_DEPTH(child) >= R_DEPTH(child)) {
475  #else
476  #ifdef AVL_COUNT
477  if(L_COUNT(child) >= R_COUNT(child)) {
478  #else
479  #error No balancing possible.
480  #endif
481  #endif
482  avlnode->left = child->right;
483  if(avlnode->left)
484  avlnode->left->parent = avlnode;
485  child->right = avlnode;
486  avlnode->parent = child;
487  *superparent = child;
488  child->parent = parent;
489  #ifdef AVL_COUNT
490  avlnode->count = CALC_COUNT(avlnode);
491  child->count = CALC_COUNT(child);
492  #endif
493  #ifdef AVL_DEPTH
494  avlnode->depth = CALC_DEPTH(avlnode);
495  child->depth = CALC_DEPTH(child);
496  #endif
497  } else {
498  gchild = child->right;
499  avlnode->left = gchild->right;
500  if(avlnode->left)
501  avlnode->left->parent = avlnode;
502  child->right = gchild->left;
503  if(child->right)
504  child->right->parent = child;
505  gchild->right = avlnode;
506  if(gchild->right)
507  gchild->right->parent = gchild;
508  gchild->left = child;
509  if(gchild->left)
510  gchild->left->parent = gchild;
511  *superparent = gchild;
512  gchild->parent = parent;
513  #ifdef AVL_COUNT
514  avlnode->count = CALC_COUNT(avlnode);
515  child->count = CALC_COUNT(child);
516  gchild->count = CALC_COUNT(gchild);
517  #endif
518  #ifdef AVL_DEPTH
519  avlnode->depth = CALC_DEPTH(avlnode);
520  child->depth = CALC_DEPTH(child);
521  gchild->depth = CALC_DEPTH(gchild);
522  #endif
523  }
524  break;
525  case 1:
526  child = avlnode->right;
527  #ifdef AVL_DEPTH
528  if(R_DEPTH(child) >= L_DEPTH(child)) {
529  #else
530  #ifdef AVL_COUNT
531  if(R_COUNT(child) >= L_COUNT(child)) {
532  #else
533  #error No balancing possible.
534  #endif
535  #endif
536  avlnode->right = child->left;
537  if(avlnode->right)
538  avlnode->right->parent = avlnode;
539  child->left = avlnode;
540  avlnode->parent = child;
541  *superparent = child;
542  child->parent = parent;
543  #ifdef AVL_COUNT
544  avlnode->count = CALC_COUNT(avlnode);
545  child->count = CALC_COUNT(child);
546  #endif
547  #ifdef AVL_DEPTH
548  avlnode->depth = CALC_DEPTH(avlnode);
549  child->depth = CALC_DEPTH(child);
550  #endif
551  } else {
552  gchild = child->left;
553  avlnode->right = gchild->left;
554  if(avlnode->right)
555  avlnode->right->parent = avlnode;
556  child->left = gchild->right;
557  if(child->left)
558  child->left->parent = child;
559  gchild->left = avlnode;
560  if(gchild->left)
561  gchild->left->parent = gchild;
562  gchild->right = child;
563  if(gchild->right)
564  gchild->right->parent = gchild;
565  *superparent = gchild;
566  gchild->parent = parent;
567  #ifdef AVL_COUNT
568  avlnode->count = CALC_COUNT(avlnode);
569  child->count = CALC_COUNT(child);
570  gchild->count = CALC_COUNT(gchild);
571  #endif
572  #ifdef AVL_DEPTH
573  avlnode->depth = CALC_DEPTH(avlnode);
574  child->depth = CALC_DEPTH(child);
575  gchild->depth = CALC_DEPTH(gchild);
576  #endif
577  }
578  break;
579  default:
580  #ifdef AVL_COUNT
581  avlnode->count = CALC_COUNT(avlnode);
582  #endif
583  #ifdef AVL_DEPTH
584  avlnode->depth = CALC_DEPTH(avlnode);
585  #endif
586  }
587  avlnode = parent;
588  }
589 }
#define R_COUNT(n)
Definition: avl.cpp:40
avl_tree_t * avl_alloc_tree(avl_compare_t cmp, avl_freeitem_t freeitem)
Definition: avl.cpp:189
void * avl_delete(avl_tree_t *avltree, const void *item)
Definition: avl.cpp:406
avl_node_t * avl_at(const avl_tree_t *avltree, unsigned int index)
Definition: avl.cpp:97
struct avl_node_t * parent
Definition: avl.h:55
struct avl_node_t * prev
Definition: avl.h:54
unsigned char depth
Definition: avl.h:63
Definition: avl.h:52
avl_node_t * avl_fixup_node(avl_tree_t *avltree, avl_node_t *newnode)
Definition: avl.cpp:410
avl_node_t * avl_insert_before(avl_tree_t *avltree, avl_node_t *node, avl_node_t *newnode)
Definition: avl.cpp:248
int avl_search_closest(const avl_tree_t *avltree, const void *item, avl_node_t **avlnode)
Definition: avl.cpp:134
void avl_unlink_node(avl_tree_t *avltree, avl_node_t *avlnode)
Definition: avl.cpp:340
avl_node_t * avl_insert_after(avl_tree_t *avltree, avl_node_t *node, avl_node_t *newnode)
Definition: avl.cpp:274
int(* avl_compare_t)(const void *, const void *)
Definition: avl.h:45
avl_node_t * tail
Definition: avl.h:69
avl_node_t * avl_insert(avl_tree_t *avltree, void *item)
Definition: avl.cpp:321
void avl_free_nodes(avl_tree_t *avltree)
Definition: avl.cpp:197
#define L_COUNT(n)
Definition: avl.cpp:39
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
unsigned int avl_index(const avl_node_t *avlnode)
Definition: avl.cpp:118
avl_freeitem_t freeitem
Definition: avl.h:72
unsigned int avl_count(const avl_tree_t *avltree)
Definition: avl.cpp:93
struct avl_node_t * left
Definition: avl.h:56
void(* avl_freeitem_t)(void *)
Definition: avl.h:50
avl_node_t * avl_insert_top(avl_tree_t *avltree, avl_node_t *newnode)
Definition: avl.cpp:241
#define NODE_COUNT(n)
Definition: avl.cpp:38
avl_node_t * avl_search(const avl_tree_t *avltree, const void *item)
Definition: avl.cpp:173
#define R_DEPTH(n)
Definition: avl.cpp:47
avl_compare_t cmp
Definition: avl.h:71
avl_tree_t * avl_init_tree(avl_tree_t *rc, avl_compare_t cmp, avl_freeitem_t freeitem)
Definition: avl.cpp:178
#define CALC_DEPTH(n)
Definition: avl.cpp:48
void * item
Definition: avl.h:58
void avl_free_tree(avl_tree_t *avltree)
Definition: avl.cpp:218
struct avl_node_t * next
Definition: avl.h:53
#define L_DEPTH(n)
Definition: avl.cpp:46
avl_node_t * avl_insert_node(avl_tree_t *avltree, avl_node_t *newnode)
Definition: avl.cpp:300
avl_node_t * head
Definition: avl.h:68
struct avl_node_t * right
Definition: avl.h:57
void avl_clear_tree(avl_tree_t *avltree)
Definition: avl.cpp:193
unsigned int count
Definition: avl.h:60
#define CALC_COUNT(n)
Definition: avl.cpp:41
void * avl_delete_node(avl_tree_t *avltree, avl_node_t *avlnode)
Definition: avl.cpp:394
avl_node_t * top
Definition: avl.h:70
avl_node_t * avl_init_node(avl_node_t *newnode, void *item)
Definition: avl.cpp:233
Definition: avl.h:67