2 /* pyavl -- File "avl.c" */
4 /* AVL trees with RANK field and parent pointers */
8 #ifdef AVL_SHOW_ERROR_ON
9 #define AVL_SHOW_ERROR(fmt,arg) fprintf(stderr, "! avl.c: " fmt, arg)
11 #define AVL_SHOW_ERROR(fmt,arg) (void) (fmt), (void) (arg)
15 avl_default_item_copy (const void *item
)
17 return (const void *) item
;
21 avl_default_item_dispose (void *item
)
23 (void)item
; /* for -Wall */
28 typedef uint32_t rbal_t
; /* integral type to encode rank and skew bits */
30 typedef UInt32 rbal_t
;
37 typedef struct avl_node
39 struct avl_node
*sub
[2];
53 avl_size_t count
; /* how many nodes in tree rooted at [root] */
54 avl_compare_func compare
; /* compare items */
55 avl_item_copy_func copy
;
56 avl_item_dispose_func dispose
;
57 avl_alloc_func alloc
; /* to allocate memory (same signature as malloc) */
58 avl_dealloc_func dealloc
; /* to deallocate memory (same signature as free) */
62 #define Item_Compare(cmp, tree, item1, item2)\
63 (*cmp)(tree->param, item1, item2)
65 /* patches (November 2004) */
68 #define CMPERR_CHECK__FIND(param) if (avl_errcmp_occurred(param)) return NULL
69 #define CMPERR_CHECK__INDEX(param) if (avl_errcmp_occurred(param)) return 0
70 #define CMPERR_CHECK__SPAN(param) if (avl_errcmp_occurred(param)) return -2
71 #define CMPERR_CHECK__INS(param) if (avl_errcmp_occurred(param)) return -2
72 #define CMPERR_CHECK__DEL(param) (avl_errcmp_occurred(param) ? -2 : 0)
73 #define CMPERR_CHECK__SPLIT(param) if (avl_errcmp_occurred(param)) return -2
74 #define CMPERR_CHECK__VERIFY(param) && (!avl_errcmp_occurred(param))
76 #define CMPERR_CHECK__FIND(param) (void) param
77 #define CMPERR_CHECK__INDEX(param) (void) param
78 #define CMPERR_CHECK__SPAN(param) (void) param
79 #define CMPERR_CHECK__INS(param) (void) param
80 #define CMPERR_CHECK__DEL(param) 0
81 #define CMPERR_CHECK__SPLIT(param) (void) param
82 #define CMPERR_CHECK__VERIFY(param) /* nothing */
85 #define sub_left(a) (a)->sub[0]
86 #define sub_right(a) (a)->sub[1]
87 #define get_item(a) (a)->item
89 /* RANK(a) = size of left subtree + 1 */
101 #define set_lskew(a)\
103 #define set_rskew(a)\
105 #define set_skew(a,d)\
106 ( rbal(a) |= (1 << d) )
107 #define unset_lskew(a)\
109 #define unset_rskew(a)\
113 #define set_rank(a,r)\
114 ( rbal(a) = (r<<2 | get_bal(a)) )
115 #define incr_rank(a,r)\
117 #define decr_rank(a,r)\
120 #define AVL_MIN_DEPTH 0
122 /*** Node management ***/
124 #define DETACH_FUNC 1 /* nonzero to use function not macro */
126 /* helper structure */
129 OP_BACKUP
, OP_DETACH
, OP_FREE
138 #define ini_ptr_handler(h,op) struct ptr_handler h = { OP_##op, NULL }
139 #define clear_node(a) \
140 sub_left(a) = NULL; \
141 sub_right(a) = NULL; \
145 /* Called by 'avl_ins', 'avl_dup', 'node_slice' */
147 new_node (void *item
, avl_node
* up
, avl_tree t
)
149 avl_node
*a
= (*t
->alloc
) (sizeof (avl_node
));
154 sub_right (a
) = NULL
;
157 a
->item
= (*t
->copy
) (item
);
163 free_node (avl_node
* a
, avl_tree t
)
165 a
->item
= (*t
->dispose
) (a
->item
);
169 #define backup_item(backup,item,t) if (backup == NULL) ; else *backup = (*t->copy)(item)
173 /* macro to detach node [a] from tree [t] */
174 #define detach_node(a,t,h) { struct ptr_handler *ch = h; \
178 else if (ch->whichop == OP_DETACH){ \
181 } else if (ch->whichop == OP_BACKUP){ \
182 ch->ptr = (*t->copy)(a->item); \
189 /* function to detach node [a] from tree [t] */
191 detach_node (avl_node
* a
, avl_tree t
, struct ptr_handler
*h
)
197 else if (h
->whichop
== OP_DETACH
)
202 else if (h
->whichop
== OP_BACKUP
)
204 h
->ptr
= (*t
->copy
) (a
->item
);
211 #endif /* DETACH_FUNC */
213 /*** Tree methods ***/
216 avl_create (avl_compare_func compare
, avl_item_copy_func copy
,
217 avl_item_dispose_func dispose
, avl_alloc_func alloc
,
218 avl_dealloc_func dealloc
, void *param
)
220 avl_tree t
= (*alloc
) (sizeof (struct avl_tree_
));
223 AVL_SHOW_ERROR ("%s\n", "couldn't create new handle in avl_create()");
229 t
->compare
= compare
;
231 t
->dispose
= dispose
;
233 t
->dealloc
= dealloc
;
238 /* Empty the tree, using rotations */
241 node_empty (avl_tree t
)
245 for (a
= t
->root
; a
!= NULL
;)
248 if (sub_right (a
) == NULL
)
252 while (sub_left (a
) != NULL
)
256 sub_left (p
) = sub_right (a
);
268 /* [t] is an existing tree handle */
270 /* this function invokes node_empty() */
273 avl_reset (avl_tree t
,
274 avl_compare_func compare
,
275 avl_item_copy_func copy
,
276 avl_item_dispose_func dispose
,
277 avl_alloc_func alloc
, avl_dealloc_func dealloc
)
282 t
->compare
= compare
;
284 t
->dispose
= dispose
;
286 t
->dealloc
= dealloc
;
290 avl_empty (avl_tree t
)
296 /* Destroy nodes, free handle */
299 avl_destroy (avl_tree t
)
301 #ifndef AVL_NULLCHECKS
310 avl_dup (avl_tree t
, void *param
)
312 #ifndef AVL_NULLCHECKS
317 avl_tree tt
= avl_create (
318 /*(avl_compare_func) */ t
->compare
,
319 /*(avl_item_copy_func) */ t
->copy
,
320 /*(avl_item_dispose_func) */ t
->dispose
,
321 /*(avl_alloc_func) */ t
->alloc
,
322 /*(avl_dealloc_func) */ t
->dealloc
,
327 AVL_SHOW_ERROR ("%s\n", "couldn't create new handle in avl_dup()");
331 tt
->count
= t
->count
;
340 tt
->root
= c
= new_node (get_item (a
), NULL
, t
);
344 sub_right (c
) = NULL
; /*!!! */
349 while (sub_left (a
) != NULL
)
352 sub_left (c
) = s
= new_node (get_item (a
), NULL
, t
);
363 while (sub_right (a
) == NULL
)
366 sub_right (c
) = NULL
;
368 /* Find successor of [a] in original tree */
376 while (s
!= sub_left (a
));
380 s
= new_node (get_item (a
), NULL
, t
);
383 sub_right (s
) = sub_right (c
);
394 sub_right (c
) = NULL
;
403 AVL_SHOW_ERROR ("%s\n", "couldn't allocate node in avl_dup()");
410 avl_isempty (avl_tree t
)
412 #ifndef AVL_NULLCHECKS
413 return t
== NULL
|| t
->root
== NULL
;
415 return t
->root
== NULL
;
420 avl_size (avl_tree t
)
422 #ifndef AVL_NULLCHECKS
423 return t
== NULL
? 0 : t
->count
;
432 int h
= AVL_MIN_DEPTH
;
434 for (; a
!= NULL
; ++h
)
435 a
= a
->sub
[is_rskew (a
)];
440 node_first (avl_node
* a
)
442 while (sub_left (a
) != NULL
)
448 node_last (avl_node
* a
)
450 while (sub_right (a
) != NULL
)
458 node_next (avl_node
* a
)
460 if (sub_right (a
) != NULL
)
461 return node_first (sub_right (a
));
470 while (a
!= NULL
&& sub_right (a
) == p
);
478 node_prev (avl_node
* a
)
480 if (sub_left (a
) != NULL
)
481 return node_last (sub_left (a
));
490 while (a
!= NULL
&& sub_left (a
) == p
);
496 node_find (const void *item
, avl_tree t
)
498 avl_node
*a
= t
->root
;
499 avl_compare_func cmp
= t
->compare
;
504 c
= Item_Compare (cmp
, t
, item
, get_item (a
));
505 CMPERR_CHECK__FIND (t
->param
);
518 avl_search (const void *item
, avl_tree t
, int *dir
)
523 avl_node
**r
= &t
->root
;
525 avl_compare_func cmp
= t
->compare
;
530 c
= Item_Compare (cmp
, t
, item
, get_item (a
));
533 r
= &a
->sub
[c
= c
> 0];
548 get_index (avl_node
* a
)
550 avl_size_t n
= get_rank (a
);
553 while ((p
= a
->up
) != NULL
)
555 if (a
!= sub_left (p
))
562 /* Find item by index */
565 node_find_index (avl_size_t idx
, avl_tree t
)
567 avl_node
*a
= t
->root
;
570 if (idx
== 0 || idx
> t
->count
)
573 return node_first (a
);
575 return node_last (a
);
577 while ((c
= (int)(idx
- get_rank (a
))) != 0)
591 /* Rebalance starting from node [a] where a->sub[d_]
592 * is deeper post-insertion
596 rebalance_ins (avl_node
* a
, int dir
, avl_tree t
)
604 incr_rank (a
, (rbal_t
)(!dir
));
611 dir
= a
!= sub_left (p
);
615 /* Now bal(a) == -1 or +1 */
616 /* Rotate if need be */
627 u
!= NULL
? &u
->sub
[a
!= sub_left (u
)] : &t
->root
;
631 if (is_lskew (sub_left (p
)))
635 sub_left (p
) = sub_right (a
);
636 if (sub_right (a
) != NULL
)
637 sub_right (a
)->up
= p
;
640 rbal (p
) -= rzero (a
);
645 a
= sub_right (sub_left (p
));
646 sub_right (sub_left (p
)) = sub_left (a
);
647 if (sub_left (a
) != NULL
)
648 sub_left (a
)->up
= sub_left (p
);
649 sub_left (p
)->up
= a
;
650 sub_left (a
) = sub_left (p
);
651 sub_left (p
) = sub_right (a
);
652 if (sub_right (a
) != NULL
)
653 sub_right (a
)->up
= p
;
657 case 0: /* not skewed */
659 unset_rskew (sub_left (a
));
661 case 1: /* left skew */
664 unset_rskew (sub_left (a
));
666 case 2: /* right skew */
668 unset_rskew (sub_left (a
));
669 set_lskew (sub_left (a
));
671 rbal (a
) += rzero (sub_left (a
));
672 rbal (p
) -= rzero (a
);
678 } /* rot or no rot ? */
691 u
!= NULL
? &u
->sub
[a
!= sub_left (u
)] : &t
->root
;
694 if (is_rskew (sub_right (p
)))
698 sub_right (p
) = sub_left (a
);
699 if (sub_left (a
) != NULL
)
700 sub_left (a
)->up
= p
;
703 rbal (a
) += rzero (p
);
708 a
= sub_left (sub_right (p
));
709 sub_left (sub_right (p
)) = sub_right (a
);
710 if (sub_right (a
) != NULL
)
711 sub_right (a
)->up
= sub_right (p
);
712 sub_right (p
)->up
= a
;
713 sub_right (a
) = sub_right (p
);
714 sub_right (p
) = sub_left (a
);
715 if (sub_left (a
) != NULL
)
716 sub_left (a
)->up
= p
;
720 case 0: /* not skewed */
722 unset_lskew (sub_right (a
));
724 case 1: /* left skew */
726 unset_lskew (sub_right (a
));
727 set_rskew (sub_right (a
));
729 case 2: /* right skew */
732 unset_lskew (sub_right (a
));
734 rbal (sub_right (a
)) -= rzero (a
);
735 rbal (a
) += rzero (p
);
743 } /* rot or not rot ? */
746 /* The tree rooted at 'a' is now valid */
747 /* Finish adjusting ranks */
749 while ((p
= a
->up
) != NULL
)
751 incr_rank (p
, (rbal_t
)(a
== sub_left (p
)));
761 /* detach [p] : non-null */
763 /* only the linkage is tweaked */
766 rebalance_del (avl_node
* p
, avl_tree t
, void **backup
)
768 avl_node
**r
, *a
, *c
;
776 r
= &a
->sub
[dir
= p
!= sub_left (a
)];
779 if (c
== NULL
&& sub_left (p
) == NULL
)
781 else if (c
== NULL
|| sub_left (p
) == NULL
)
783 *r
= c
!= NULL
? c
: sub_left (p
);
788 if (sub_left (c
) == NULL
)
797 while (sub_left (c
) != NULL
);
800 sub_left (a
) = sub_right (c
);
801 if (sub_right (c
) != NULL
)
802 sub_right (c
)->up
= a
;
803 sub_right (c
) = sub_right (p
);
804 sub_right (c
)->up
= c
;
806 sub_left (c
) = sub_left (p
);
807 sub_left (c
)->up
= c
;
813 backup_item (backup
, p
->item
, t
);
814 detach_node (p
, t
, NULL
);
816 /* Start backtracking : subtree of [a] in direction [dir] is less deep */
818 for (;; a
= (*r
)->up
)
823 decr_rank (a
, (rbal_t
)(!dir
));
837 dir
= a
!= sub_left (a
->up
);
838 r
= &a
->up
->sub
[dir
];
845 bal
= get_bal (sub_right (p
));
851 sub_right (p
) = sub_left (a
);
852 if (sub_left (a
) != NULL
)
853 sub_left (a
)->up
= p
;
862 rbal (a
) += rzero (p
);
867 a
= sub_left (sub_right (p
));
868 sub_left (sub_right (p
)) = sub_right (a
);
869 if (sub_right (a
) != NULL
)
870 sub_right (a
)->up
= sub_right (p
);
871 sub_right (p
)->up
= a
;
872 sub_right (a
) = sub_right (p
);
873 sub_right (p
) = sub_left (a
);
874 if (sub_left (a
) != NULL
)
875 sub_left (a
)->up
= p
;
879 case 0: /* not skewed */
881 unset_lskew (sub_right (a
));
883 case 1: /* left skew */
885 unset_lskew (sub_right (a
));
886 set_rskew (sub_right (a
));
888 case 2: /* right skew */
891 unset_lskew (sub_right (a
));
894 rbal (sub_right (a
)) -= rzero (a
);
895 rbal (a
) += rzero (p
);
901 /* Done with rotation */
920 dir
= a
!= sub_left (a
->up
);
921 r
= &a
->up
->sub
[dir
];
928 bal
= get_bal (sub_left (p
));
934 sub_left (p
) = sub_right (a
);
935 if (sub_right (a
) != NULL
)
936 sub_right (a
)->up
= p
;
945 rbal (p
) -= rzero (a
);
950 a
= sub_right (sub_left (p
));
951 sub_right (sub_left (p
)) = sub_left (a
);
952 if (sub_left (a
) != NULL
)
953 sub_left (a
)->up
= sub_left (p
);
954 sub_left (p
)->up
= a
;
955 sub_left (a
) = sub_left (p
);
956 sub_left (p
) = sub_right (a
);
957 if (sub_right (a
) != NULL
)
958 sub_right (a
)->up
= p
;
962 case 0: /* not skewed */
964 unset_rskew (sub_left (a
));
966 case 1: /* left skew */
969 unset_rskew (sub_left (a
));
971 case 2: /* right skew */
973 unset_rskew (sub_left (a
));
974 set_lskew (sub_left (a
));
977 rbal (a
) += rzero (sub_left (a
));
978 rbal (p
) -= rzero (a
);
983 /* Done with rotation */
988 } /* if dir==0 else 1 */
991 /* Finish adjusting ranks */
992 while ((p
= a
->up
) != NULL
)
994 decr_rank (p
, (rbal_t
)(a
== sub_left (p
)));
1002 avl_first (avl_tree t
)
1004 #ifndef AVL_NULLCHECKS
1005 if (t
== NULL
|| t
->root
== NULL
)
1007 if (t
->root
== NULL
)
1010 return get_item (node_first (t
->root
));
1014 avl_last (avl_tree t
)
1016 #ifndef AVL_NULLCHECKS
1017 if (t
== NULL
|| t
->root
== NULL
)
1019 if (t
->root
== NULL
)
1022 return get_item (node_last (t
->root
));
1026 avl_find (const void *item
, avl_tree t
)
1030 #ifndef AVL_NULLCHECKS
1034 a
= node_find (item
, t
);
1035 return a
!= NULL
? get_item (a
) : NULL
;
1039 * Return smallest index i in [1:len] s.t. tree[i] matches [item],
1040 * or zero if not found
1044 avl_index (const void *item
, avl_tree t
)
1046 #ifndef AVL_NULLCHECKS
1047 if (item
== NULL
|| t
== NULL
|| t
->root
== NULL
)
1049 if (t
->root
== NULL
)
1054 avl_compare_func cmp
= t
->compare
;
1056 avl_size_t idx
= 0, n
= 0;
1061 c
= Item_Compare (cmp
, t
, item
, get_item (a
));
1062 CMPERR_CHECK__INDEX (t
->param
);
1064 idx
= n
+ get_rank (a
);
1076 * lo smallest index s.t. t[lo] >= lo_item, or t->count+1 and
1077 * hi greatest index s.t. t[hi] <= hi_item, or 0
1080 avl_span (const void *lo_item
,
1081 const void *hi_item
,
1082 avl_tree t
, avl_size_t
* lo_idx
, avl_size_t
* hi_idx
)
1084 *lo_idx
= t
->count
+ 1;
1087 #ifndef AVL_NULLCHECKS
1088 if (t
== NULL
|| t
->root
== NULL
)
1090 if (t
->root
== NULL
)
1095 avl_compare_func cmp
= t
->compare
;
1100 c
= Item_Compare (cmp
, t
, lo_item
, hi_item
) > 0;
1101 CMPERR_CHECK__SPAN (t
->param
);
1104 const void *temp
= lo_item
;
1113 c
= Item_Compare (cmp
, t
, lo_item
, get_item (a
));
1114 CMPERR_CHECK__SPAN (t
->param
);
1122 *lo_idx
= n
+ get_rank (a
);
1131 c
= Item_Compare (cmp
, t
, hi_item
, get_item (a
));
1132 CMPERR_CHECK__SPAN (t
->param
);
1139 *hi_idx
+= get_rank (a
);
1149 * Find the smallest item in tree [t] that is GEQ the passed item
1153 avl_find_atleast (const void *item
, avl_tree t
)
1155 #ifndef AVL_NULLCHECKS
1156 if (t
== NULL
|| t
->root
== NULL
)
1158 if (t
->root
== NULL
)
1162 avl_compare_func cmp
= t
->compare
;
1163 avl_node
*a
= t
->root
;
1169 c
= Item_Compare (cmp
, t
, item
, get_item (a
));
1170 CMPERR_CHECK__FIND (t
->param
);
1187 * Find the greatest item in tree [t] that is LEQ the passed item
1191 avl_find_atmost (const void *item
, avl_tree t
)
1193 #ifndef AVL_NULLCHECKS
1194 if (t
== NULL
|| t
->root
== NULL
)
1196 if (t
->root
== NULL
)
1200 avl_compare_func cmp
= t
->compare
;
1201 avl_node
*a
= t
->root
;
1207 c
= Item_Compare (cmp
, t
, item
, get_item (a
));
1208 CMPERR_CHECK__FIND (t
->param
);
1224 /* Retrieve item of index [idx] in tree [t] */
1227 avl_find_index (avl_size_t idx
, avl_tree t
)
1231 #ifndef AVL_NULLCHECKS
1235 a
= node_find_index (idx
, t
);
1236 return a
!= NULL
? get_item (a
) : NULL
;
1239 #define attach_node(ptr,up,t)\
1240 ptr = new_node(item, up, t);\
1242 AVL_SHOW_ERROR("%s\n", "couldn't allocate node");\
1247 /* Iterative insertion */
1250 avl_ins (void *item
, avl_tree t
, avl_bool_t allow_duplicates
)
1252 #ifndef AVL_NULLCHECKS
1257 avl_compare_func cmp
= t
->compare
;
1261 for (r
= &t
->root
, a
= NULL
; *r
!= NULL
; r
= &a
->sub
[dir
= dir
> 0])
1264 dir
= Item_Compare (cmp
, t
, item
, get_item (a
));
1265 CMPERR_CHECK__INS (t
->param
);
1266 if (!dir
&& !allow_duplicates
)
1270 attach_node (*r
, a
, t
);
1272 return rebalance_ins (a
, dir
, t
);
1274 #ifndef AVL_NULLCHECKS
1275 } /* end if non-empty tree */
1280 avl_del (void *item
, avl_tree t
, void **backup
)
1282 #ifndef AVL_NULLCHECKS
1283 if (t
== NULL
|| t
->root
== NULL
)
1285 if (t
->root
== NULL
)
1289 avl_node
*a
= node_find (item
, t
);
1292 return CMPERR_CHECK__DEL (t
->param
);
1293 return rebalance_del (a
, t
, backup
);
1297 /* helper function */
1299 node_del_first (avl_tree t
, struct ptr_handler
*h
)
1301 avl_node
*p
, *a
, *c
;
1304 p
= node_first (t
->root
);
1306 if (sub_right (p
) != NULL
)
1307 sub_right (p
)->up
= a
;
1309 t
->root
= sub_right (p
);
1311 sub_left (a
) = sub_right (p
);
1313 detach_node (p
, t
, h
);
1315 /* Start backtracking : subtree of [a] in direction [0] is less deep */
1336 bal
= get_bal (sub_right (p
));
1342 sub_right (p
) = sub_left (a
);
1343 if (sub_left (a
) != NULL
)
1344 sub_left (a
)->up
= p
;
1353 rbal (a
) += rzero (p
);
1358 a
= sub_left (sub_right (p
));
1359 sub_left (sub_right (p
)) = sub_right (a
);
1360 if (sub_right (a
) != NULL
)
1361 sub_right (a
)->up
= sub_right (p
);
1362 sub_right (p
)->up
= a
;
1363 sub_right (a
) = sub_right (p
);
1364 sub_right (p
) = sub_left (a
);
1365 if (sub_left (a
) != NULL
)
1366 sub_left (a
)->up
= p
;
1368 switch (get_bal (a
))
1370 case 0: /* not skewed */
1372 unset_lskew (sub_right (a
));
1374 case 1: /* left skew */
1376 unset_lskew (sub_right (a
));
1377 set_rskew (sub_right (a
));
1379 case 2: /* right skew */
1382 unset_lskew (sub_right (a
));
1385 rbal (sub_right (a
)) -= rzero (a
);
1386 rbal (a
) += rzero (p
);
1391 /* Done with rotation */
1398 } /* if getbal(a) */
1401 /* Finish adjusting ranks */
1402 while ((a
= a
->up
) != NULL
)
1410 /* helper function */
1412 node_del_last (avl_tree t
, struct ptr_handler
*h
)
1415 avl_node
*p
, *a
, *c
;
1418 p
= node_last (t
->root
);
1420 if (sub_left (p
) != NULL
)
1421 sub_left (p
)->up
= a
;
1423 t
->root
= sub_left (p
);
1425 sub_right (a
) = sub_left (p
);
1427 detach_node (p
, t
, h
);
1429 /* Start backtracking : subtree of [a] in direction [1] is less deep */
1448 bal
= get_bal (sub_left (p
));
1454 sub_left (p
) = sub_right (a
);
1455 if (sub_right (a
) != NULL
)
1456 sub_right (a
)->up
= p
;
1465 rbal (p
) -= rzero (a
);
1470 a
= sub_right (sub_left (p
));
1471 sub_right (sub_left (p
)) = sub_left (a
);
1472 if (sub_left (a
) != NULL
)
1473 sub_left (a
)->up
= sub_left (p
);
1474 sub_left (p
)->up
= a
;
1475 sub_left (a
) = sub_left (p
);
1476 sub_left (p
) = sub_right (a
);
1477 if (sub_right (a
) != NULL
)
1478 sub_right (a
)->up
= p
;
1480 switch (get_bal (a
))
1482 case 0: /* not skewed */
1484 unset_rskew (sub_left (a
));
1486 case 1: /* left skew */
1489 unset_rskew (sub_left (a
));
1491 case 2: /* right skew */
1493 unset_rskew (sub_left (a
));
1494 set_lskew (sub_left (a
));
1497 rbal (a
) += rzero (sub_left (a
));
1498 rbal (p
) -= rzero (a
);
1503 /* Done with rotation */
1510 } /* if getbal(a) */
1516 /* [p] : juncture node (zeroed out) */
1518 /* [n] : rank of [p] in resulting tree */
1520 /* [delta] = depth_1 - depth_0 */
1523 join_left (avl_node
* p
, avl_node
** r0
, avl_node
* r1
, int delta
, int n
)
1525 avl_node
*a
= NULL
, **r
= r0
;
1532 n
-= (int)get_rank (a
);
1541 delta
+= (int)(is_lskew (a
) + 1);
1542 n
-= (int)get_rank (a
);
1552 /* at this point bal(*r) = -1 or 0 */
1569 /* Rotate if need be */
1570 /* No (+2,0) rotation to do */
1579 if (is_rskew (sub_right (p
)))
1583 sub_right (p
) = sub_left (a
);
1584 if (sub_left (a
) != NULL
)
1585 sub_left (a
)->up
= p
;
1588 rbal (a
) += rzero (p
);
1593 a
= sub_left (sub_right (p
));
1594 sub_left (sub_right (p
)) = sub_right (a
);
1595 if (sub_right (a
) != NULL
)
1596 sub_right (a
)->up
= sub_right (p
);
1597 sub_right (p
)->up
= a
;
1598 sub_right (a
) = sub_right (p
);
1599 sub_right (p
) = sub_left (a
);
1600 if (sub_left (a
) != NULL
)
1601 sub_left (a
)->up
= p
;
1603 switch (get_bal (a
))
1605 case 0: /* not skewed */
1607 unset_lskew (sub_right (a
));
1609 case 1: /* left skew */
1611 unset_lskew (sub_right (a
));
1612 set_rskew (sub_right (a
));
1614 case 2: /* right skew */
1617 unset_lskew (sub_right (a
));
1619 rbal (sub_right (a
)) -= rzero (a
);
1620 rbal (a
) += rzero (p
);
1627 sub_right (a
->up
) = a
;
1630 } /* rot or not rot */
1635 /* [p] : juncture node */
1637 /* [n] : rank of [p] in resulting tree */
1640 join_right (avl_node
* p
, avl_node
* r0
, avl_node
** r1
, int delta
, int n
)
1642 avl_node
*a
= NULL
, **r
= r1
;
1649 incr_rank (a
, (rbal_t
)n
);
1659 delta
-= (int)(is_rskew (a
) + 1);
1660 incr_rank (a
, (rbal_t
)n
);
1670 /* at this point bal(*r) = +1 or 0 */
1687 /* Rotate if need be */
1688 /* No (-2,0) rotation to do */
1697 if (is_lskew (sub_left (p
)))
1701 sub_left (p
) = sub_right (a
);
1702 if (sub_right (a
) != NULL
)
1703 sub_right (a
)->up
= p
;
1706 rbal (p
) -= rzero (a
);
1711 a
= sub_right (sub_left (p
));
1712 sub_right (sub_left (p
)) = sub_left (a
);
1713 if (sub_left (a
) != NULL
)
1714 sub_left (a
)->up
= sub_left (p
);
1715 sub_left (p
)->up
= a
;
1716 sub_left (a
) = sub_left (p
);
1717 sub_left (p
) = sub_right (a
);
1718 if (sub_right (a
) != NULL
)
1719 sub_right (a
)->up
= p
;
1721 switch (get_bal (a
))
1723 case 0: /* not skewed */
1725 unset_rskew (sub_left (a
));
1727 case 1: /* left skew */
1730 unset_rskew (sub_left (a
));
1732 case 2: /* right skew */
1734 unset_rskew (sub_left (a
));
1735 set_lskew (sub_left (a
));
1737 rbal (a
) += rzero (sub_left (a
));
1738 rbal (p
) -= rzero (a
);
1739 } /* end which rot */
1745 sub_left (a
->up
) = a
;
1748 } /* end rot or not rot */
1754 avl_del_first (avl_tree t
, void **backup
)
1756 #ifndef AVL_NULLCHECKS
1757 if (t
== NULL
|| t
->root
== NULL
)
1759 if (t
->root
== NULL
)
1767 rv
= node_del_first (t
, NULL
);
1771 ini_ptr_handler (h
, BACKUP
);
1772 rv
= node_del_first (t
, &h
);
1780 avl_del_last (avl_tree t
, void **backup
)
1782 #ifndef AVL_NULLCHECKS
1783 if (t
== NULL
|| t
->root
== NULL
)
1785 if (t
->root
== NULL
)
1793 rv
= node_del_last (t
, NULL
);
1797 ini_ptr_handler (h
, BACKUP
);
1798 rv
= node_del_last (t
, &h
);
1806 avl_ins_index (void *item
, avl_size_t idx
, avl_tree t
)
1810 if (idx
== 0 || t
== NULL
|| idx
> t
->count
+ 1)
1813 attach_node (p
, NULL
, t
);
1814 /* Note: 'attach_node' macro increments t->count */
1818 return join_right (p
, (avl_node
*) NULL
, &t
->root
, /*delta= */ 0, 1);
1820 else if (idx
== t
->count
)
1823 join_left (p
, &t
->root
, (avl_node
*) NULL
, /*delta= */ 0, (int)t
->count
);
1827 avl_node
*a
= node_find_index (idx
- 1, t
);
1830 if (sub_right (a
) != NULL
)
1832 a
= node_first (sub_right (a
));
1843 return rebalance_ins (a
, dir
, t
);
1848 avl_del_index (avl_size_t idx
, avl_tree t
, void **backup
)
1850 #ifndef AVL_NULLCHECKS
1855 if (idx
== 0 || idx
> t
->count
)
1858 return avl_del_first (t
, backup
);
1859 if (idx
== t
->count
)
1860 return avl_del_last (t
, backup
);
1862 avl_node
*a
= node_find_index (idx
, t
);
1864 return rebalance_del (a
, t
, backup
);
1869 * Outcome: [t0] handles the concatenation of [t0] and [t1]
1873 avl_cat (avl_tree t0
, avl_tree t1
)
1875 #ifndef AVL_NULLCHECKS
1876 if (t0
== NULL
|| t1
== NULL
|| t1
->root
== NULL
)
1878 if (t1
->root
== NULL
)
1882 if (t0
->root
== NULL
)
1884 t0
->root
= t1
->root
;
1885 t0
->count
= t1
->count
;
1892 int delta
= depth (t1
->root
) - depth (t0
->root
);
1894 ini_ptr_handler (h
, DETACH
);
1898 if (node_del_first (t1
, &h
) == 2)
1900 (void) join_left ((avl_node
*) h
.ptr
, &t0
->root
, t1
->root
, delta
,
1901 (int)(t0
->count
+ 1));
1905 if (node_del_last (t0
, &h
) == 2)
1907 (void) join_right ((avl_node
*) h
.ptr
, t0
->root
, &t1
->root
, delta
,
1908 (int)(t0
->count
+ 1));
1909 t0
->root
= t1
->root
;
1913 t0
->count
+= t1
->count
+ 1;
1919 * - [t0] and [t1] are existing handles
1920 * - See Donald Knuth, TAOCP Vol.3 "Sorting and searching"
1924 avl_split (const void *item
, avl_tree t
, avl_tree t0
, avl_tree t1
)
1926 #ifndef AVL_NULLCHECKS
1927 if (t
== NULL
|| t
->root
== NULL
)
1929 if (t
->root
== NULL
)
1930 #endif /* AVL_NULLCHECKS */
1939 avl_compare_func cmp
= t
->compare
;
1940 avl_node
*a
, *p
, *sn
; /* sn: split node */
1941 int d_
, k
, na
, an
[AVL_STACK_CAPACITY
];
1943 /* invariant: [na]= size of tree rooted at [a] plus one */
1945 for (a
= t
->root
, na
= (int)(t
->count
+ 1), k
= 0;;)
1947 d_
= Item_Compare (cmp
, t
, item
, get_item (a
));
1948 CMPERR_CHECK__SPLIT (t
->param
);
1951 p
= a
->sub
[d_
= d_
> 0];
1956 na
-= (int)get_rank (a
);
1958 na
= (int)get_rank (a
);
1962 /* record split node */
1967 t0
->root
= sub_left (a
);
1968 t1
->root
= sub_right (a
);
1969 if (t0
->root
!= NULL
)
1970 t0
->root
->up
= NULL
;
1971 if (t1
->root
!= NULL
)
1972 t1
->root
->up
= NULL
;
1973 t0
->count
= get_rank (a
) - 1;
1974 t1
->count
= t
->count
- get_rank (a
);
1978 avl_node
*r
[2], *rr
;
1980 avl_size_t n
[2], nn
;
1982 r
[0] = sub_left (a
);
1983 r
[1] = sub_right (a
);
1989 h
[0] = ha
- (is_rskew (a
) ? 2 : 1);
1990 h
[1] = ha
- (is_lskew (a
) ? 2 : 1);
1991 n
[0] = get_rank (a
); /* size of r[0] plus one */
1992 n
[1] = (avl_size_t
)na
- n
[0]; /* size of r[1] plus one */
1994 for (p
= a
->up
, d_
= a
!= sub_left (p
);;)
1997 a
= p
; /* a: juncture node */
2003 ha
+= (is_rskew (a
) ? 2 : 1);
2004 h
[1] = ha
- (is_lskew (a
) ? 2 : 1);
2006 n
[1] += (avl_size_t
)(an
[k
- 1] - (int)get_rank (a
));
2008 d_
= a
!= sub_left (p
);
2014 r
[1] = sub_right (a
);
2017 h
[1] += (2 == join_right (a
, rr
, r
+ 1, h
[1] - hh
, (int)nn
));
2023 join_left (a
, r
+ 1, sub_right (a
), h
[1] - hh
,
2030 ha
+= (is_lskew (a
) ? 2 : 1);
2031 h
[0] = ha
- (is_rskew (a
) ? 2 : 1);
2035 d_
= a
!= sub_left (p
);
2041 r
[0] = sub_left (a
);
2044 h
[0] += (2 == join_left (a
, r
, rr
, hh
- h
[0], (int)nn
));
2050 join_right (a
, sub_left (a
), r
, hh
- h
[0], (int)nn
));
2060 t0
->count
= n
[0] - 1;
2061 t1
->count
= n
[1] - 1;
2064 /* Detach split node */
2065 detach_node (sn
, t
, NULL
);
2073 /* Inorder traversal */
2076 avl_walk (avl_tree t
, avl_item_func proc
, void *param
)
2078 #ifndef AVL_NULLCHECKS
2079 if (t
== NULL
|| t
->root
== NULL
)
2081 if (t
->root
== NULL
)
2086 avl_node
*a
= t
->root
, *p
;
2090 while (sub_left (a
) != NULL
)
2095 (*proc
) (get_item (a
), param
);
2096 if (sub_right (a
) != NULL
)
2105 while (p
!= sub_left (a
));
2112 /* recursive helper for 'avl_slice' */
2114 node_slice (avl_node
** root
, avl_node
** cur
, avl_tree tree
, avl_size_t len
)
2116 avl_size_t mid
= len
/ 2;
2120 if ((*root
= new_node ((*cur
)->item
, /*parent */ NULL
, tree
)) == NULL
)
2122 sub_left (*root
) = NULL
;
2123 sub_right (*root
) = NULL
;
2125 *cur
= node_next (*cur
);
2129 else if ((*root
= new_node (NULL
, /*parent */ NULL
, tree
)) == NULL
)
2135 avl_node
*p
= *root
;
2138 rbal (p
) = (mid
+ 1) << 2;
2140 if ((h0
= node_slice (&sub_left (p
), cur
, tree
, mid
)) < 0)
2143 p
->item
= (*tree
->copy
) ((*cur
)->item
);
2144 sub_left (p
)->up
= p
;
2146 *cur
= node_next (*cur
);
2150 if ((h1
= node_slice (&sub_right (p
), cur
, tree
, len
)) < 0)
2152 sub_right (p
)->up
= p
;
2166 /* Return a slice t[lo,hi) as a new tree */
2169 avl_slice (avl_tree t
, avl_size_t lo_idx
, avl_size_t hi_idx
, void *param
)
2171 #ifndef AVL_NULLCHECKS
2174 #endif /* AVL_NULLCHECKS */
2176 if (lo_idx
> hi_idx
|| lo_idx
> t
->count
)
2180 if (hi_idx
> t
->count
+ 1)
2181 hi_idx
= t
->count
+ 1;
2184 avl_tree tt
= avl_create (t
->compare
,
2193 AVL_SHOW_ERROR ("%s\n",
2194 "couldn't allocate new handle in avl_slice()");
2198 if (lo_idx
< hi_idx
)
2200 avl_node
*cur
= node_find_index (lo_idx
, t
);
2202 if (node_slice (&tt
->root
, &cur
, t
, tt
->count
= hi_idx
- lo_idx
) < 0)
2204 AVL_SHOW_ERROR ("%s\n", "couldn't allocate node in avl_slice()");
2209 tt
->root
->up
= NULL
;
2215 /* recursive helper for 'avl_xload' */
2218 node_load (avl_node
** root
, avl_itersource cur
, void **pres
, avl_tree desc
,
2221 avl_size_t mid
= len
/ 2;
2225 if (0 != (*cur
->f
) (cur
, pres
)
2226 || (*root
= new_node (*pres
, /*parent */ NULL
, desc
)) == NULL
)
2228 sub_left (*root
) = NULL
;
2229 sub_right (*root
) = NULL
;
2234 else if ((*root
= new_node (NULL
, /*parent */ NULL
, desc
)) == NULL
)
2240 avl_node
*p
= *root
;
2243 rbal (p
) = (mid
+ 1) << 2;
2245 if ((h0
= node_load (&sub_left (p
), cur
, pres
, desc
, mid
)) < 0)
2248 if (0 != (*cur
->f
) (cur
, pres
))
2251 p
->item
= (*desc
->copy
) (*pres
);
2252 sub_left (p
)->up
= p
;
2256 if ((h1
= node_load (&sub_right (p
), cur
, pres
, desc
, len
)) < 0)
2258 sub_right (p
)->up
= p
;
2272 /* Load 'len' items from itersource */
2275 avl_xload (avl_itersource src
, void **pres
, avl_size_t len
, avl_config conf
,
2278 #ifndef AVL_NULLCHECKS
2282 #endif /* AVL_NULLCHECKS */
2284 avl_tree tt
= avl_create (conf
->compare
,
2293 AVL_SHOW_ERROR ("%s\n", "couldn't allocate new handle in avl_load()");
2299 if (node_load (&tt
->root
, src
, pres
, tt
, tt
->count
= len
) < 0)
2301 AVL_SHOW_ERROR ("%s\n", "couldn't allocate node in avl_load()");
2303 (*tt
->dealloc
) (tt
);
2306 tt
->root
->up
= NULL
;
2309 #ifndef AVL_NULLCHECKS
2314 #ifdef HAVE_AVL_VERIFY
2316 /* Verification routine */
2330 avl_error (avl_verify_code err
)
2332 static char *errmess
[] = {
2337 "Differential mismatch",
2341 AVL_SHOW_ERROR ("Invalid avl_tree: %s\n", errmess
[err
- 1]);
2345 static int bals
[] = { 1, 0, 2 };
2348 helper for recursive 'avl_verify' function
2352 static avl_verify_code
2353 node_verify (avl_node
* root
, avl_tree tree
, int *h
, avl_size_t
* c
,
2356 avl_verify_code err
= okay
;
2359 *h
= AVL_MIN_DEPTH
, *c
= 0;
2362 #define AVL_ASSERT(expr,n) if (expr) ; else { err = n; break; }
2363 #define CHECK(err) if (err) break
2365 avl_node
*left
, *right
;
2369 left
= sub_left (root
);
2370 right
= sub_right (root
);
2373 AVL_ASSERT (root
->up
== up
, bad_parent
);
2374 CHECK (err
= node_verify (left
, tree
, h_
, c_
, root
));
2375 AVL_ASSERT (get_rank (root
) == *c_
+ 1, bad_rank
);
2376 CHECK (err
= node_verify (right
, tree
, h_
+ 1, c_
+ 1, root
));
2377 delta
= h_
[1] - h_
[0];
2378 AVL_ASSERT (delta
>= -1 && delta
<= +1, out_of_balance
);
2379 AVL_ASSERT (get_bal (root
) == bals
[delta
+ 1], diff_mismatch
);
2380 AVL_ASSERT (left
== NULL
2381 || (Item_Compare (tree
->compare
, tree
, get_item (left
),
2383 0 CMPERR_CHECK__VERIFY (tree
->param
)),
2385 AVL_ASSERT (right
== NULL
2388 (tree
->compare
, tree
, get_item (root
),
2389 get_item (right
)) <=
2390 0 CMPERR_CHECK__VERIFY (tree
->param
)), out_of_order
);
2391 *h
= 1 + (h_
[0] > h_
[1] ? h_
[0] : h_
[1]);
2392 *c
= 1 + c_
[0] + c_
[1];
2400 avl_verify (avl_tree t
)
2402 #ifndef AVL_NULLCHECKS
2405 #endif /* AVL_NULLCHECKS */
2409 avl_verify_code err
;
2411 err
= node_verify (t
->root
, t
, &h
, &c
, (avl_node
*) NULL
);
2413 return avl_error (err
);
2415 return avl_error (count_mismatch
);
2419 #endif /* HAVE_AVL_VERIFY */
2435 struct avl_iterator_
2439 avl_status_t status
;
2442 #define get_root(i) i->tree->root
2443 #define is_pre(i) i->status == AVL_ITERATOR_PRE
2444 #define is_post(i) i->status == AVL_ITERATOR_POST
2445 #define set_pre_iterator(i) i->status = AVL_ITERATOR_PRE
2446 #define set_post_iterator(i) i->status = AVL_ITERATOR_POST
2447 #define set_in_iterator(i) i->status = AVL_ITERATOR_INTREE
2449 /* Position existing iterator [iter] at node matching [item] in its own tree,
2450 * if it exists ; otherwise do nothing
2454 avl_iterator_seek (const void *item
, avl_iterator iter
)
2456 avl_node
*p
= node_find (item
, iter
->tree
);
2460 set_in_iterator (iter
);
2466 avl_iterator_seek_index (avl_size_t idx
, avl_iterator iter
)
2468 avl_node
*p
= node_find_index (idx
, iter
->tree
);
2472 set_in_iterator (iter
);
2477 /* Return item pointer at current position */
2480 avl_iterator_cur (avl_iterator iter
)
2482 return iter
->pos
!= NULL
? get_item (iter
->pos
) : NULL
;
2486 avl_iterator_count (avl_iterator iter
)
2488 return iter
->tree
->count
;
2492 avl_iterator_index (avl_iterator iter
)
2494 if (iter
->pos
!= NULL
)
2495 return get_index (iter
->pos
);
2496 else if (is_pre (iter
))
2499 return iter
->tree
->count
+ 1;
2505 avl_iterator_new (avl_tree t
, avl_ini_t ini
, ...)
2508 avl_iterator iter
= NULL
;
2510 va_start (args
, ini
);
2515 if ((iter
= (*t
->alloc
) (sizeof (struct avl_iterator_
))) == NULL
)
2517 AVL_SHOW_ERROR ("%s\n", "couldn't create iterator");
2524 if (ini
!= AVL_ITERATOR_INI_INTREE
)
2527 (ini
== AVL_ITERATOR_INI_PRE
) ? AVL_ITERATOR_PRE
: AVL_ITERATOR_POST
;
2531 const void *item
= NULL
;
2533 item
= va_arg (args
, const void *);
2535 set_pre_iterator (iter
);
2538 AVL_SHOW_ERROR ("%s\n", "missing argument to avl_iterator_new()");
2540 avl_iterator_seek (item
, iter
);
2549 * The following used to write to memory after it was freed.
2550 * Corrected by: David Turner <novalis@openplans.org>
2553 avl_iterator_kill (avl_iterator iter
)
2557 avl_dealloc_func dealloc
= iter
->tree
->dealloc
;
2565 avl_iterator_next (avl_iterator iter
)
2567 avl_node
*a
= iter
->pos
;
2574 a
= get_root (iter
);
2578 set_in_iterator (iter
);
2585 set_post_iterator (iter
);
2589 return a
!= NULL
? get_item (a
) : NULL
;
2593 avl_iterator_prev (avl_iterator iter
)
2595 avl_node
*a
= iter
->pos
;
2602 a
= get_root (iter
);
2606 set_in_iterator (iter
);
2613 set_pre_iterator (iter
);
2617 return a
!= NULL
? get_item (a
) : NULL
;
2620 /* Remove node at current position */
2622 /* Move cursor to next position */
2625 avl_iterator_del (avl_iterator iter
, void **backup
)
2627 if (iter
== NULL
|| iter
->pos
== NULL
)
2630 avl_node
*a
= iter
->pos
, *p
;
2634 set_post_iterator (iter
);
2636 return rebalance_del (a
, iter
->tree
, backup
);