2 * Copyright (C) 1995-1997 by Sam Rushing <rushing@nightmare.com>
6 * Permission to use, copy, modify, and distribute this software and
7 * its documentation for any purpose and without fee is hereby
8 * granted, provided that the above copyright notice appear in all
9 * copies and that both that copyright notice and this permission
10 * notice appear in supporting documentation, and that the name of Sam
11 * Rushing not be used in advertising or publicity pertaining to
12 * distribution of the software without specific, written prior
15 * SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 /* $Id: avl.c,v 1.11 2004/01/27 02:16:25 karl Exp $ */
28 * This is a fairly straightfoward translation of a prototype
29 * written in python, 'avl_tree.py'. Read that file first.
42 avl_node_new (void * key
,
45 avl_node
* node
= (avl_node
*) malloc (sizeof (avl_node
));
50 node
->parent
= parent
;
54 node
->rank_and_balance
= 0;
55 AVL_SET_BALANCE (node
, 0);
56 AVL_SET_RANK (node
, 1);
57 thread_rwlock_create(&node
->rwlock
);
63 avl_tree_new (avl_key_compare_fun_type compare_fun
,
66 avl_tree
* t
= (avl_tree
*) malloc (sizeof (avl_tree
));
71 avl_node
* root
= avl_node_new((void *)NULL
, (avl_node
*) NULL
);
78 t
->compare_fun
= compare_fun
;
79 t
->compare_arg
= compare_arg
;
80 thread_rwlock_create(&t
->rwlock
);
87 avl_tree_free_helper (avl_node
* node
, avl_free_key_fun_type free_key_fun
)
90 avl_tree_free_helper (node
->left
, free_key_fun
);
93 free_key_fun (node
->key
);
95 avl_tree_free_helper (node
->right
, free_key_fun
);
97 thread_rwlock_destroy (&node
->rwlock
);
102 avl_tree_free (avl_tree
* tree
, avl_free_key_fun_type free_key_fun
)
105 avl_tree_free_helper (tree
->root
->right
, free_key_fun
);
108 thread_rwlock_destroy(&tree
->root
->rwlock
);
111 thread_rwlock_destroy(&tree
->rwlock
);
116 avl_insert (avl_tree
* ob
,
119 if (!(ob
->root
->right
)) {
120 avl_node
* node
= avl_node_new (key
, ob
->root
);
124 ob
->root
->right
= node
;
125 ob
->length
= ob
->length
+ 1;
128 } else { /* not self.right == None */
129 avl_node
*t
, *p
, *s
, *q
, *r
;
136 if (ob
->compare_fun (ob
->compare_arg
, key
, p
->key
) < 1) {
138 AVL_SET_RANK (p
, (AVL_GET_RANK (p
) + 1));
142 avl_node
* q_node
= avl_node_new (key
, p
);
150 } else if (AVL_GET_BALANCE(q
)) {
160 avl_node
* q_node
= avl_node_new (key
, p
);
168 } else if (AVL_GET_BALANCE(q
)) {
176 ob
->length
= ob
->length
+ 1;
178 /* adjust balance factors */
179 if (ob
->compare_fun (ob
->compare_arg
, key
, s
->key
) < 1) {
185 if (ob
->compare_fun (ob
->compare_arg
, key
, p
->key
) < 1) {
186 AVL_SET_BALANCE (p
, -1);
189 AVL_SET_BALANCE (p
, +1);
196 if (ob
->compare_fun (ob
->compare_arg
, key
, s
->key
) < 1) {
202 if (AVL_GET_BALANCE (s
) == 0) {
203 AVL_SET_BALANCE (s
, a
);
204 ob
->height
= ob
->height
+ 1;
206 } else if (AVL_GET_BALANCE (s
) == -a
) {
207 AVL_SET_BALANCE (s
, 0);
209 } else if (AVL_GET_BALANCE(s
) == a
) {
210 if (AVL_GET_BALANCE (r
) == a
) {
211 /* single rotation */
216 r
->right
->parent
= s
;
220 AVL_SET_RANK (s
, (AVL_GET_RANK (s
) - AVL_GET_RANK (r
)));
228 AVL_SET_RANK (r
, (AVL_GET_RANK (r
) + AVL_GET_RANK (s
)));
230 AVL_SET_BALANCE (s
, 0);
231 AVL_SET_BALANCE (r
, 0);
232 } else if (AVL_GET_BALANCE (r
) == -a
) {
233 /* double rotation */
244 p
->right
->parent
= s
;
248 AVL_SET_RANK (p
, (AVL_GET_RANK (p
) + AVL_GET_RANK (r
)));
249 AVL_SET_RANK (s
, (AVL_GET_RANK (s
) - AVL_GET_RANK (p
)));
254 p
->right
->parent
= r
;
264 AVL_SET_RANK (r
, (AVL_GET_RANK (r
) - AVL_GET_RANK (p
)));
265 AVL_SET_RANK (p
, (AVL_GET_RANK (p
) + AVL_GET_RANK (s
)));
267 if (AVL_GET_BALANCE (p
) == a
) {
268 AVL_SET_BALANCE (s
, -a
);
269 AVL_SET_BALANCE (r
, 0);
270 } else if (AVL_GET_BALANCE (p
) == -a
) {
271 AVL_SET_BALANCE (s
, 0);
272 AVL_SET_BALANCE (r
, a
);
274 AVL_SET_BALANCE (s
, 0);
275 AVL_SET_BALANCE (r
, 0);
277 AVL_SET_BALANCE (p
, 0);
279 /* finishing touch */
292 avl_get_by_index (avl_tree
* tree
,
294 void ** value_address
)
296 avl_node
* p
= tree
->root
->right
;
297 unsigned long m
= index
+ 1;
302 if (m
< AVL_GET_RANK(p
)) {
304 } else if (m
> AVL_GET_RANK(p
)) {
305 m
= m
- AVL_GET_RANK(p
);
308 *value_address
= p
->key
;
315 avl_get_by_key (avl_tree
* tree
,
317 void **value_address
)
319 avl_node
* x
= tree
->root
->right
;
324 int compare_result
= tree
->compare_fun (tree
->compare_arg
, key
, x
->key
);
325 if (compare_result
< 0) {
331 } else if (compare_result
> 0) {
338 *value_address
= x
->key
;
344 int avl_delete(avl_tree
*tree
, void *key
, avl_free_key_fun_type free_key_fun
)
346 avl_node
*x
, *y
, *p
, *q
, *r
, *top
, *x_child
;
347 int shortened_side
, shorter
;
349 x
= tree
->root
->right
;
354 int compare_result
= tree
->compare_fun (tree
->compare_arg
, key
, x
->key
);
355 if (compare_result
< 0) {
357 * We will be deleting from the left, adjust this node's
360 AVL_SET_RANK (x
, (AVL_GET_RANK(x
) - 1));
364 /* Oops! now we have to undo the rank changes
365 * all the way up the tree
367 AVL_SET_RANK(x
, (AVL_GET_RANK (x
) + 1));
368 while (x
!= tree
->root
->right
) {
369 if (x
->parent
->left
== x
) {
370 AVL_SET_RANK(x
->parent
, (AVL_GET_RANK (x
->parent
) + 1));
374 return -1; /* key not in tree */
376 } else if (compare_result
> 0) {
381 AVL_SET_RANK(x
, (AVL_GET_RANK (x
) + 1));
382 while (x
!= tree
->root
->right
) {
383 if (x
->parent
->left
== x
) {
384 AVL_SET_RANK(x
->parent
, (AVL_GET_RANK (x
->parent
) + 1));
388 return -1; /* key not in tree */
395 if (x
->left
&& x
->right
) {
398 /* The complicated case.
399 * reduce this to the simple case where we are deleting
400 * a node with at most one child.
403 /* find the immediate predecessor <y> */
408 /* swap <x> with <y> */
412 /* we know <x>'s left subtree lost a node because that's
413 * where we took it from
415 AVL_SET_RANK (x
, (AVL_GET_RANK (x
) - 1));
418 /* now <x> has at most one child
419 * scoot this child into the place of <x>
423 x_child
->parent
= x
->parent
;
424 } else if (x
->right
) {
426 x_child
->parent
= x
->parent
;
431 /* now tell <x>'s parent that a grandchild became a child */
432 if (x
== x
->parent
->left
) {
433 x
->parent
->left
= x_child
;
436 x
->parent
->right
= x_child
;
441 * the height of the subtree <x>
442 * has now been shortened. climb back up
443 * the tree, rotating when necessary to adjust
449 /* return the key and node to storage */
451 free_key_fun (x
->key
);
452 thread_rwlock_destroy (&x
->rwlock
);
455 while (shorter
&& p
->parent
) {
457 /* case 1: height unchanged */
458 if (AVL_GET_BALANCE(p
) == 0) {
459 if (shortened_side
== -1) {
460 /* we removed a left child, the tree is now heavier
463 AVL_SET_BALANCE (p
, +1);
465 /* we removed a right child, the tree is now heavier
468 AVL_SET_BALANCE (p
, -1);
472 } else if (AVL_GET_BALANCE (p
) == shortened_side
) {
473 /* case 2: taller subtree shortened, height reduced */
474 AVL_SET_BALANCE (p
, 0);
476 /* case 3: shorter subtree shortened */
478 /* set <q> to the taller of the two subtrees of <p> */
479 if (shortened_side
== 1) {
484 if (AVL_GET_BALANCE (q
) == 0) {
485 /* case 3a: height unchanged */
486 if (shortened_side
== -1) {
487 /* single rotate left */
488 q
->parent
= p
->parent
;
495 AVL_SET_RANK (q
, (AVL_GET_RANK (q
) + AVL_GET_RANK (p
)));
497 /* single rotate right */
498 q
->parent
= p
->parent
;
501 q
->right
->parent
= p
;
505 AVL_SET_RANK (p
, (AVL_GET_RANK (p
) - AVL_GET_RANK (q
)));
508 AVL_SET_BALANCE (q
, shortened_side
);
509 AVL_SET_BALANCE (p
, (- shortened_side
));
510 } else if (AVL_GET_BALANCE (q
) == AVL_GET_BALANCE (p
)) {
511 /* case 3b: height reduced */
512 if (shortened_side
== -1) {
513 /* single rotate left */
514 q
->parent
= p
->parent
;
521 AVL_SET_RANK (q
, (AVL_GET_RANK (q
) + AVL_GET_RANK (p
)));
523 /* single rotate right */
524 q
->parent
= p
->parent
;
527 q
->right
->parent
= p
;
531 AVL_SET_RANK (p
, (AVL_GET_RANK (p
) - AVL_GET_RANK (q
)));
534 AVL_SET_BALANCE (q
, 0);
535 AVL_SET_BALANCE (p
, 0);
537 /* case 3c: height reduced, balance factors opposite */
538 if (shortened_side
== 1) {
539 /* double rotate right */
540 /* first, a left rotation around q */
542 r
->parent
= p
->parent
;
549 /* now, a right rotation around p */
552 r
->right
->parent
= p
;
556 AVL_SET_RANK (r
, (AVL_GET_RANK (r
) + AVL_GET_RANK (q
)));
557 AVL_SET_RANK (p
, (AVL_GET_RANK (p
) - AVL_GET_RANK (r
)));
559 /* double rotate left */
560 /* first, a right rotation around q */
562 r
->parent
= p
->parent
;
565 r
->right
->parent
= q
;
569 /* now a left rotation around p */
576 AVL_SET_RANK (q
, (AVL_GET_RANK (q
) - AVL_GET_RANK (r
)));
577 AVL_SET_RANK (r
, (AVL_GET_RANK (r
) + AVL_GET_RANK (p
)));
579 if (AVL_GET_BALANCE (r
) == shortened_side
) {
580 AVL_SET_BALANCE (q
, (- shortened_side
));
581 AVL_SET_BALANCE (p
, 0);
582 } else if (AVL_GET_BALANCE (r
) == (- shortened_side
)) {
583 AVL_SET_BALANCE (q
, 0);
584 AVL_SET_BALANCE (p
, shortened_side
);
586 AVL_SET_BALANCE (q
, 0);
587 AVL_SET_BALANCE (p
, 0);
589 AVL_SET_BALANCE (r
, 0);
592 /* a rotation has caused <q> (or <r> in case 3c) to become
593 * the root. let <p>'s former parent know this.
595 if (top
->left
== p
) {
605 /* shortened_side tells us which side we came up from */
611 } /* end while(shorter) */
612 /* when we're all done, we're one shorter */
613 tree
->length
= tree
->length
- 1;
618 avl_iterate_inorder_helper (avl_node
* node
,
619 avl_iter_fun_type iter_fun
,
624 result
= avl_iterate_inorder_helper (node
->left
, iter_fun
, iter_arg
);
629 result
= (iter_fun (node
->key
, iter_arg
));
634 result
= avl_iterate_inorder_helper (node
->right
, iter_fun
, iter_arg
);
643 avl_iterate_inorder (avl_tree
* tree
,
644 avl_iter_fun_type iter_fun
,
650 result
= avl_iterate_inorder_helper (tree
->root
->right
, iter_fun
, iter_arg
);
657 avl_node
*avl_get_first(avl_tree
*tree
)
661 node
= tree
->root
->right
;
662 if (node
== NULL
|| node
->key
== NULL
) return NULL
;
670 avl_node
*avl_get_prev(avl_node
*node
)
674 while (node
->right
) {
680 avl_node
*child
= node
;
681 while (node
->parent
&& node
->parent
->key
) {
683 if (child
== node
->right
) {
693 avl_node
*avl_get_next(avl_node
*node
)
703 avl_node
*child
= node
;
704 while (node
->parent
&& node
->parent
->key
) {
706 if (child
== node
->left
) {
716 /* iterate a function over a range of indices, using get_predecessor */
719 avl_iterate_index_range (avl_tree
* tree
,
720 avl_iter_index_fun_type iter_fun
,
726 unsigned long num_left
;
729 if (high
> tree
->length
) {
732 num_left
= (high
- low
);
733 /* find the <high-1>th node */
735 node
= tree
->root
->right
;
737 if (m
< AVL_GET_RANK (node
)) {
739 } else if (m
> AVL_GET_RANK (node
)) {
740 m
= m
- AVL_GET_RANK (node
);
746 /* call <iter_fun> on <node>, <get_pred(node)>, ... */
748 num_left
= num_left
- 1;
749 if (iter_fun (num_left
, node
->key
, iter_arg
) != 0) {
752 node
= avl_get_prev (node
);
757 /* If <key> is present in the tree, return that key's node, and set <*index>
758 * appropriately. If not, return NULL, and set <*index> to the position
759 * representing the closest preceding value.
763 avl_get_index_by_key (avl_tree
* tree
,
765 unsigned long * index
)
767 avl_node
* x
= tree
->root
->right
;
773 m
= AVL_GET_RANK (x
);
776 int compare_result
= tree
->compare_fun (tree
->compare_arg
, key
, x
->key
);
777 if (compare_result
< 0) {
779 m
= m
- AVL_GET_RANK(x
);
781 m
= m
+ AVL_GET_RANK(x
);
786 } else if (compare_result
> 0) {
789 m
= m
+ AVL_GET_RANK(x
);
801 /* return the (low index, high index) pair that spans the given key */
804 avl_get_span_by_key (avl_tree
* tree
,
807 unsigned long * high
)
809 unsigned long m
, i
, j
;
812 node
= avl_get_index_by_key (tree
, key
, &m
);
814 /* did we find an exact match?
815 * if so, we have to search left and right
816 * to find the span, since we know nothing about
817 * the arrangement of like keys.
820 avl_node
* left
, * right
;
822 left
= avl_get_prev (node
);
824 while ((i
> 0) && (tree
->compare_fun (tree
->compare_arg
, key
, left
->key
) == 0)) {
825 left
= avl_get_prev (left
);
829 right
= avl_get_next (node
);
831 while ((j
<= tree
->length
) && (tree
->compare_fun (tree
->compare_arg
, key
, right
->key
) == 0)) {
832 right
= avl_get_next (right
);
844 /* return the (low index, high index) pair that spans the given key */
847 avl_get_span_by_two_keys (avl_tree
* tree
,
851 unsigned long * high
)
854 avl_node
* low_node
, * high_node
;
857 /* we may need to swap them */
858 order
= tree
->compare_fun (tree
->compare_arg
, low_key
, high_key
);
860 void * temp
= low_key
;
865 low_node
= avl_get_index_by_key (tree
, low_key
, &i
);
866 high_node
= avl_get_index_by_key (tree
, high_key
, &j
);
871 left
= avl_get_prev (low_node
);
872 while ((i
> 0) && (tree
->compare_fun (tree
->compare_arg
, low_key
, left
->key
) == 0)) {
873 left
= avl_get_prev (left
);
882 right
= avl_get_next (high_node
);
883 while ((j
<= tree
->length
) && (tree
->compare_fun (tree
->compare_arg
, high_key
, right
->key
) == 0)) {
884 right
= avl_get_next (right
);
898 avl_get_item_by_key_most (avl_tree
* tree
,
900 void **value_address
)
902 avl_node
* x
= tree
->root
->right
;
903 *value_address
= NULL
;
909 int compare_result
= tree
->compare_fun (tree
->compare_arg
, key
, x
->key
);
911 if (compare_result
== 0) {
912 *value_address
= x
->key
;
914 } else if (compare_result
< 0) {
915 /* the given key is less than the current key */
925 /* the given key is more than the current key */
926 /* save this value, it might end up being the right one! */
927 *value_address
= x
->key
;
929 /* there is a bigger entry */
942 avl_get_item_by_key_least (avl_tree
* tree
,
944 void **value_address
)
946 avl_node
* x
= tree
->root
->right
;
947 *value_address
= NULL
;
953 int compare_result
= tree
->compare_fun (tree
->compare_arg
, key
, x
->key
);
954 if (compare_result
== 0) {
955 *value_address
= x
->key
;
956 return 0; /* exact match */
957 } else if (compare_result
< 0) {
958 /* the given key is less than the current key */
959 /* save this value, it might end up being the right one! */
960 *value_address
= x
->key
;
964 if (*value_address
) /* we have found a valid entry */
971 /* there is a bigger entry */
974 if (*value_address
) /* we have found a valid entry */
983 #define AVL_MAX(X, Y) ((X) > (Y) ? (X) : (Y))
986 avl_verify_balance (avl_node
* node
)
991 long lh
= avl_verify_balance (node
->left
);
992 long rh
= avl_verify_balance (node
->right
);
993 if ((rh
- lh
) != AVL_GET_BALANCE(node
)) {
996 if (((lh
- rh
) > 1) || ((lh
- rh
) < -1)) {
999 return (1 + AVL_MAX (lh
, rh
));
1004 avl_verify_parent (avl_node
* node
, avl_node
* parent
)
1006 if (node
->parent
!= parent
) {
1010 avl_verify_parent (node
->left
, node
);
1013 avl_verify_parent (node
->right
, node
);
1018 avl_verify_rank (avl_node
* node
)
1023 unsigned long num_left
=0, num_right
=0;
1025 num_left
= avl_verify_rank (node
->left
);
1028 num_right
= avl_verify_rank (node
->right
);
1030 if (AVL_GET_RANK (node
) != num_left
+ 1) {
1031 fprintf (stderr
, "invalid rank at node %ld\n", (long) node
->key
);
1034 return (num_left
+ num_right
+ 1);
1038 /* sanity-check the tree */
1041 avl_verify (avl_tree
* tree
)
1044 avl_verify_balance (tree
->root
->right
);
1045 avl_verify_parent (tree
->root
->right
, tree
->root
);
1046 avl_verify_rank (tree
->root
->right
);
1052 * These structures are accumulated on the stack during print_tree
1053 * and are used to keep track of the width and direction of each
1054 * branch in the history of a particular line <node>.
1057 typedef struct _link_node
{
1058 struct _link_node
* parent
;
1063 static char balance_chars
[3] = {'\\', '-', '/'};
1066 default_key_printer (char * buffer
, void * key
)
1068 return sprintf (buffer
, "%p", key
);
1072 * When traveling the family tree, a change in direction
1073 * indicates when to print a connector. This is kinda crazy,
1074 * we use the stack to build a linked list, and then travel
1075 * it backwards using recursion.
1079 print_connectors (link_node
* link
)
1082 print_connectors (link
->parent
);
1084 if (link
->parent
&& (link
->parent
->direction
!= link
->direction
) && (link
->parent
->parent
)) {
1086 fprintf (stdout
, "|");
1087 for (i
=0; i
< (link
->width
- 1); i
++) {
1088 fprintf (stdout
, " ");
1092 for (i
=0; i
< (link
->width
); i
++) {
1093 fprintf (stdout
, " ");
1099 * The <key_printer> function writes a representation of the
1100 * key into <buffer> (which is conveniently fixed in size to add
1101 * the spice of danger). It should return the size of the
1106 print_node (avl_key_printer_fun_type key_printer
,
1112 width
= key_printer (buffer
, node
->key
);
1118 here
.width
= width
+ 11;
1119 print_node (key_printer
, node
->right
, &here
);
1121 print_connectors (link
);
1122 fprintf (stdout
, "+-[%c %s %03d]",
1123 balance_chars
[AVL_GET_BALANCE(node
)+1],
1125 (int)AVL_GET_RANK(node
));
1126 if (node
->left
|| node
->right
) {
1127 fprintf (stdout
, "-|\n");
1129 fprintf (stdout
, "\n");
1134 here
.direction
= -1;
1135 here
.width
= width
+ 11;
1136 print_node (key_printer
, node
->left
, &here
);
1141 avl_print_tree (avl_tree
* tree
, avl_key_printer_fun_type key_printer
)
1143 link_node top
= {NULL
, 0, 0};
1145 key_printer
= default_key_printer
;
1148 print_node (key_printer
, tree
->root
->right
, &top
);
1150 fprintf (stdout
, "<empty tree>\n");
1155 void avl_tree_rlock(avl_tree
*tree
)
1157 thread_rwlock_rlock(&tree
->rwlock
);
1160 void avl_tree_wlock(avl_tree
*tree
)
1162 thread_rwlock_wlock(&tree
->rwlock
);
1165 void avl_tree_unlock(avl_tree
*tree
)
1167 thread_rwlock_unlock(&tree
->rwlock
);
1170 void avl_node_rlock(avl_node
*node
)
1172 thread_rwlock_rlock(&node
->rwlock
);
1175 void avl_node_wlock(avl_node
*node
)
1177 thread_rwlock_wlock(&node
->rwlock
);
1180 void avl_node_unlock(avl_node
*node
)
1182 thread_rwlock_unlock(&node
->rwlock
);