1 /* Produced by texiweb from libavl.w. */
3 /* libavl - library for manipulation of binary trees.
4 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 /* Creates and returns a new table
31 with comparison function |compare| using parameter |param|
32 and memory allocator |allocator|.
33 Returns |NULL| if memory allocation failed. */
35 avl_create (avl_comparison_func
*compare
, void *param
,
36 struct libavl_allocator
*allocator
)
38 struct avl_table
*tree
;
40 assert (compare
!= NULL
);
42 if (allocator
== NULL
)
43 allocator
= &avl_allocator_default
;
45 tree
= allocator
->libavl_malloc (allocator
, sizeof *tree
);
49 tree
->avl_root
= NULL
;
50 tree
->avl_compare
= compare
;
51 tree
->avl_param
= param
;
52 tree
->avl_alloc
= allocator
;
54 tree
->avl_generation
= 0;
59 /* Search |tree| for an item matching |item|, and return it if found.
60 Otherwise return |NULL|. */
62 avl_find (const struct avl_table
*tree
, const void *item
)
64 const struct avl_node
*p
;
66 assert (tree
!= NULL
&& item
!= NULL
);
67 for (p
= tree
->avl_root
; p
!= NULL
; )
69 int cmp
= tree
->avl_compare (item
, p
->avl_data
, tree
->avl_param
);
82 /* Inserts |item| into |tree| and returns a pointer to |item|'s address.
83 If a duplicate item is found in the tree,
84 returns a pointer to the duplicate without inserting |item|.
85 Returns |NULL| in case of memory allocation failure. */
87 avl_probe (struct avl_table
*tree
, void *item
)
89 struct avl_node
*y
, *z
; /* Top node to update balance factor, and parent. */
90 struct avl_node
*p
, *q
; /* Iterator, and parent. */
91 struct avl_node
*n
; /* Newly inserted node. */
92 struct avl_node
*w
; /* New root of rebalanced subtree. */
93 int dir
; /* Direction to descend. */
95 unsigned char da
[AVL_MAX_HEIGHT
]; /* Cached comparison results. */
96 int k
= 0; /* Number of cached results. */
98 assert (tree
!= NULL
&& item
!= NULL
);
100 z
= (struct avl_node
*) &tree
->avl_root
;
103 for (q
= z
, p
= y
; p
!= NULL
; q
= p
, p
= p
->avl_link
[dir
])
105 int cmp
= tree
->avl_compare (item
, p
->avl_data
, tree
->avl_param
);
109 if (p
->avl_balance
!= 0)
111 da
[k
++] = dir
= cmp
> 0;
114 n
= q
->avl_link
[dir
] =
115 tree
->avl_alloc
->libavl_malloc (tree
->avl_alloc
, sizeof *n
);
121 n
->avl_link
[0] = n
->avl_link
[1] = NULL
;
126 for (p
= y
, k
= 0; p
!= n
; p
= p
->avl_link
[da
[k
]], k
++)
132 if (y
->avl_balance
== -2)
134 struct avl_node
*x
= y
->avl_link
[0];
135 if (x
->avl_balance
== -1)
138 y
->avl_link
[0] = x
->avl_link
[1];
140 x
->avl_balance
= y
->avl_balance
= 0;
144 assert (x
->avl_balance
== +1);
146 x
->avl_link
[1] = w
->avl_link
[0];
148 y
->avl_link
[0] = w
->avl_link
[1];
150 if (w
->avl_balance
== -1)
151 x
->avl_balance
= 0, y
->avl_balance
= +1;
152 else if (w
->avl_balance
== 0)
153 x
->avl_balance
= y
->avl_balance
= 0;
154 else /* |w->avl_balance == +1| */
155 x
->avl_balance
= -1, y
->avl_balance
= 0;
159 else if (y
->avl_balance
== +2)
161 struct avl_node
*x
= y
->avl_link
[1];
162 if (x
->avl_balance
== +1)
165 y
->avl_link
[1] = x
->avl_link
[0];
167 x
->avl_balance
= y
->avl_balance
= 0;
171 assert (x
->avl_balance
== -1);
173 x
->avl_link
[0] = w
->avl_link
[1];
175 y
->avl_link
[1] = w
->avl_link
[0];
177 if (w
->avl_balance
== +1)
178 x
->avl_balance
= 0, y
->avl_balance
= -1;
179 else if (w
->avl_balance
== 0)
180 x
->avl_balance
= y
->avl_balance
= 0;
181 else /* |w->avl_balance == -1| */
182 x
->avl_balance
= +1, y
->avl_balance
= 0;
188 z
->avl_link
[y
!= z
->avl_link
[0]] = w
;
190 tree
->avl_generation
++;
194 /* Inserts |item| into |table|.
195 Returns |NULL| if |item| was successfully inserted
196 or if a memory allocation error occurred.
197 Otherwise, returns the duplicate item. */
199 avl_insert (struct avl_table
*table
, void *item
)
201 void **p
= avl_probe (table
, item
);
202 return p
== NULL
|| *p
== item
? NULL
: *p
;
205 /* Inserts |item| into |table|, replacing any duplicate item.
206 Returns |NULL| if |item| was inserted without replacing a duplicate,
207 or if a memory allocation error occurred.
208 Otherwise, returns the item that was replaced. */
210 avl_replace (struct avl_table
*table
, void *item
)
212 void **p
= avl_probe (table
, item
);
213 if (p
== NULL
|| *p
== item
)
223 /* Deletes from |tree| and returns an item matching |item|.
224 Returns a null pointer if no matching item found. */
226 avl_delete (struct avl_table
*tree
, const void *item
)
228 /* Stack of nodes. */
229 struct avl_node
*pa
[AVL_MAX_HEIGHT
]; /* Nodes. */
230 unsigned char da
[AVL_MAX_HEIGHT
]; /* |avl_link[]| indexes. */
231 int k
; /* Stack pointer. */
233 struct avl_node
*p
; /* Traverses tree to find node to delete. */
234 int cmp
; /* Result of comparison between |item| and |p|. */
236 assert (tree
!= NULL
&& item
!= NULL
);
239 p
= (struct avl_node
*) &tree
->avl_root
;
240 for (cmp
= -1; cmp
!= 0;
241 cmp
= tree
->avl_compare (item
, p
->avl_data
, tree
->avl_param
))
248 p
= p
->avl_link
[dir
];
254 if (p
->avl_link
[1] == NULL
)
255 pa
[k
- 1]->avl_link
[da
[k
- 1]] = p
->avl_link
[0];
258 struct avl_node
*r
= p
->avl_link
[1];
259 if (r
->avl_link
[0] == NULL
)
261 r
->avl_link
[0] = p
->avl_link
[0];
262 r
->avl_balance
= p
->avl_balance
;
263 pa
[k
- 1]->avl_link
[da
[k
- 1]] = r
;
277 if (s
->avl_link
[0] == NULL
)
283 s
->avl_link
[0] = p
->avl_link
[0];
284 r
->avl_link
[0] = s
->avl_link
[1];
285 s
->avl_link
[1] = p
->avl_link
[1];
286 s
->avl_balance
= p
->avl_balance
;
288 pa
[j
- 1]->avl_link
[da
[j
- 1]] = s
;
294 tree
->avl_alloc
->libavl_free (tree
->avl_alloc
, p
);
299 struct avl_node
*y
= pa
[k
];
304 if (y
->avl_balance
== +1)
306 else if (y
->avl_balance
== +2)
308 struct avl_node
*x
= y
->avl_link
[1];
309 if (x
->avl_balance
== -1)
312 assert (x
->avl_balance
== -1);
314 x
->avl_link
[0] = w
->avl_link
[1];
316 y
->avl_link
[1] = w
->avl_link
[0];
318 if (w
->avl_balance
== +1)
319 x
->avl_balance
= 0, y
->avl_balance
= -1;
320 else if (w
->avl_balance
== 0)
321 x
->avl_balance
= y
->avl_balance
= 0;
322 else /* |w->avl_balance == -1| */
323 x
->avl_balance
= +1, y
->avl_balance
= 0;
325 pa
[k
- 1]->avl_link
[da
[k
- 1]] = w
;
329 y
->avl_link
[1] = x
->avl_link
[0];
331 pa
[k
- 1]->avl_link
[da
[k
- 1]] = x
;
332 if (x
->avl_balance
== 0)
339 x
->avl_balance
= y
->avl_balance
= 0;
346 if (y
->avl_balance
== -1)
348 else if (y
->avl_balance
== -2)
350 struct avl_node
*x
= y
->avl_link
[0];
351 if (x
->avl_balance
== +1)
354 assert (x
->avl_balance
== +1);
356 x
->avl_link
[1] = w
->avl_link
[0];
358 y
->avl_link
[0] = w
->avl_link
[1];
360 if (w
->avl_balance
== -1)
361 x
->avl_balance
= 0, y
->avl_balance
= +1;
362 else if (w
->avl_balance
== 0)
363 x
->avl_balance
= y
->avl_balance
= 0;
364 else /* |w->avl_balance == +1| */
365 x
->avl_balance
= -1, y
->avl_balance
= 0;
367 pa
[k
- 1]->avl_link
[da
[k
- 1]] = w
;
371 y
->avl_link
[0] = x
->avl_link
[1];
373 pa
[k
- 1]->avl_link
[da
[k
- 1]] = x
;
374 if (x
->avl_balance
== 0)
381 x
->avl_balance
= y
->avl_balance
= 0;
388 tree
->avl_generation
++;
389 return (void *) item
;
392 /* Refreshes the stack of parent pointers in |trav|
393 and updates its generation number. */
395 trav_refresh (struct avl_traverser
*trav
)
397 assert (trav
!= NULL
);
399 trav
->avl_generation
= trav
->avl_table
->avl_generation
;
401 if (trav
->avl_node
!= NULL
)
403 avl_comparison_func
*cmp
= trav
->avl_table
->avl_compare
;
404 void *param
= trav
->avl_table
->avl_param
;
405 struct avl_node
*node
= trav
->avl_node
;
408 trav
->avl_height
= 0;
409 for (i
= trav
->avl_table
->avl_root
; i
!= node
; )
411 assert (trav
->avl_height
< AVL_MAX_HEIGHT
);
414 trav
->avl_stack
[trav
->avl_height
++] = i
;
415 i
= i
->avl_link
[cmp (node
->avl_data
, i
->avl_data
, param
) > 0];
420 /* Initializes |trav| for use with |tree|
421 and selects the null node. */
423 avl_t_init (struct avl_traverser
*trav
, struct avl_table
*tree
)
425 trav
->avl_table
= tree
;
426 trav
->avl_node
= NULL
;
427 trav
->avl_height
= 0;
428 trav
->avl_generation
= tree
->avl_generation
;
431 /* Initializes |trav| for |tree|
432 and selects and returns a pointer to its least-valued item.
433 Returns |NULL| if |tree| contains no nodes. */
435 avl_t_first (struct avl_traverser
*trav
, struct avl_table
*tree
)
439 assert (tree
!= NULL
&& trav
!= NULL
);
441 trav
->avl_table
= tree
;
442 trav
->avl_height
= 0;
443 trav
->avl_generation
= tree
->avl_generation
;
447 while (x
->avl_link
[0] != NULL
)
449 assert (trav
->avl_height
< AVL_MAX_HEIGHT
);
450 trav
->avl_stack
[trav
->avl_height
++] = x
;
455 return x
!= NULL
? x
->avl_data
: NULL
;
458 /* Initializes |trav| for |tree|
459 and selects and returns a pointer to its greatest-valued item.
460 Returns |NULL| if |tree| contains no nodes. */
462 avl_t_last (struct avl_traverser
*trav
, struct avl_table
*tree
)
466 assert (tree
!= NULL
&& trav
!= NULL
);
468 trav
->avl_table
= tree
;
469 trav
->avl_height
= 0;
470 trav
->avl_generation
= tree
->avl_generation
;
474 while (x
->avl_link
[1] != NULL
)
476 assert (trav
->avl_height
< AVL_MAX_HEIGHT
);
477 trav
->avl_stack
[trav
->avl_height
++] = x
;
482 return x
!= NULL
? x
->avl_data
: NULL
;
485 /* Searches for |item| in |tree|.
486 If found, initializes |trav| to the item found and returns the item
488 If there is no matching item, initializes |trav| to the null item
489 and returns |NULL|. */
491 avl_t_find (struct avl_traverser
*trav
, struct avl_table
*tree
, void *item
)
493 struct avl_node
*p
, *q
;
495 assert (trav
!= NULL
&& tree
!= NULL
&& item
!= NULL
);
496 trav
->avl_table
= tree
;
497 trav
->avl_height
= 0;
498 trav
->avl_generation
= tree
->avl_generation
;
499 for (p
= tree
->avl_root
; p
!= NULL
; p
= q
)
501 int cmp
= tree
->avl_compare (item
, p
->avl_data
, tree
->avl_param
);
507 else /* |cmp == 0| */
513 assert (trav
->avl_height
< AVL_MAX_HEIGHT
);
514 trav
->avl_stack
[trav
->avl_height
++] = p
;
517 trav
->avl_height
= 0;
518 trav
->avl_node
= NULL
;
522 /* Attempts to insert |item| into |tree|.
523 If |item| is inserted successfully, it is returned and |trav| is
524 initialized to its location.
525 If a duplicate is found, it is returned and |trav| is initialized to
526 its location. No replacement of the item occurs.
527 If a memory allocation failure occurs, |NULL| is returned and |trav|
528 is initialized to the null item. */
530 avl_t_insert (struct avl_traverser
*trav
, struct avl_table
*tree
, void *item
)
534 assert (trav
!= NULL
&& tree
!= NULL
&& item
!= NULL
);
536 p
= avl_probe (tree
, item
);
539 trav
->avl_table
= tree
;
542 ((char *) p
- offsetof (struct avl_node
, avl_data
)));
543 trav
->avl_generation
= tree
->avl_generation
- 1;
548 avl_t_init (trav
, tree
);
553 /* Initializes |trav| to have the same current node as |src|. */
555 avl_t_copy (struct avl_traverser
*trav
, const struct avl_traverser
*src
)
557 assert (trav
!= NULL
&& src
!= NULL
);
561 trav
->avl_table
= src
->avl_table
;
562 trav
->avl_node
= src
->avl_node
;
563 trav
->avl_generation
= src
->avl_generation
;
564 if (trav
->avl_generation
== trav
->avl_table
->avl_generation
)
566 trav
->avl_height
= src
->avl_height
;
567 memcpy (trav
->avl_stack
, (const void *) src
->avl_stack
,
568 sizeof *trav
->avl_stack
* trav
->avl_height
);
572 return trav
->avl_node
!= NULL
? trav
->avl_node
->avl_data
: NULL
;
575 /* Returns the next data item in inorder
576 within the tree being traversed with |trav|,
577 or if there are no more data items returns |NULL|. */
579 avl_t_next (struct avl_traverser
*trav
)
583 assert (trav
!= NULL
);
585 if (trav
->avl_generation
!= trav
->avl_table
->avl_generation
)
591 return avl_t_first (trav
, trav
->avl_table
);
593 else if (x
->avl_link
[1] != NULL
)
595 assert (trav
->avl_height
< AVL_MAX_HEIGHT
);
596 trav
->avl_stack
[trav
->avl_height
++] = x
;
599 while (x
->avl_link
[0] != NULL
)
601 assert (trav
->avl_height
< AVL_MAX_HEIGHT
);
602 trav
->avl_stack
[trav
->avl_height
++] = x
;
612 if (trav
->avl_height
== 0)
614 trav
->avl_node
= NULL
;
619 x
= trav
->avl_stack
[--trav
->avl_height
];
621 while (y
== x
->avl_link
[1]);
628 /* Returns the previous data item in inorder
629 within the tree being traversed with |trav|,
630 or if there are no more data items returns |NULL|. */
632 avl_t_prev (struct avl_traverser
*trav
)
636 assert (trav
!= NULL
);
638 if (trav
->avl_generation
!= trav
->avl_table
->avl_generation
)
644 return avl_t_last (trav
, trav
->avl_table
);
646 else if (x
->avl_link
[0] != NULL
)
648 assert (trav
->avl_height
< AVL_MAX_HEIGHT
);
649 trav
->avl_stack
[trav
->avl_height
++] = x
;
652 while (x
->avl_link
[1] != NULL
)
654 assert (trav
->avl_height
< AVL_MAX_HEIGHT
);
655 trav
->avl_stack
[trav
->avl_height
++] = x
;
665 if (trav
->avl_height
== 0)
667 trav
->avl_node
= NULL
;
672 x
= trav
->avl_stack
[--trav
->avl_height
];
674 while (y
== x
->avl_link
[0]);
681 /* Returns |trav|'s current item. */
683 avl_t_cur (struct avl_traverser
*trav
)
685 assert (trav
!= NULL
);
687 return trav
->avl_node
!= NULL
? trav
->avl_node
->avl_data
: NULL
;
690 /* Replaces the current item in |trav| by |new| and returns the item replaced.
691 |trav| must not have the null item selected.
692 The new item must not upset the ordering of the tree. */
694 avl_t_replace (struct avl_traverser
*trav
, void *new)
698 assert (trav
!= NULL
&& trav
->avl_node
!= NULL
&& new != NULL
);
699 old
= trav
->avl_node
->avl_data
;
700 trav
->avl_node
->avl_data
= new;
704 /* Destroys |new| with |avl_destroy (new, destroy)|,
705 first setting right links of nodes in |stack| within |new|
706 to null pointers to avoid touching uninitialized data. */
708 copy_error_recovery (struct avl_node
**stack
, int height
,
709 struct avl_table
*new, avl_item_func
*destroy
)
711 assert (stack
!= NULL
&& height
>= 0 && new != NULL
);
713 for (; height
> 2; height
-= 2)
714 stack
[height
- 1]->avl_link
[1] = NULL
;
715 avl_destroy (new, destroy
);
718 /* Copies |org| to a newly created tree, which is returned.
719 If |copy != NULL|, each data item in |org| is first passed to |copy|,
720 and the return values are inserted into the tree,
721 with |NULL| return values taken as indications of failure.
722 On failure, destroys the partially created new tree,
723 applying |destroy|, if non-null, to each item in the new tree so far,
725 If |allocator != NULL|, it is used for allocation in the new tree.
726 Otherwise, the same allocator used for |org| is used. */
728 avl_copy (const struct avl_table
*org
, avl_copy_func
*copy
,
729 avl_item_func
*destroy
, struct libavl_allocator
*allocator
)
731 struct avl_node
*stack
[2 * (AVL_MAX_HEIGHT
+ 1)];
734 struct avl_table
*new;
735 const struct avl_node
*x
;
738 assert (org
!= NULL
);
739 new = avl_create (org
->avl_compare
, org
->avl_param
,
740 allocator
!= NULL
? allocator
: org
->avl_alloc
);
743 new->avl_count
= org
->avl_count
;
744 if (new->avl_count
== 0)
747 x
= (const struct avl_node
*) &org
->avl_root
;
748 y
= (struct avl_node
*) &new->avl_root
;
751 while (x
->avl_link
[0] != NULL
)
753 assert (height
< 2 * (AVL_MAX_HEIGHT
+ 1));
756 new->avl_alloc
->libavl_malloc (new->avl_alloc
,
757 sizeof *y
->avl_link
[0]);
758 if (y
->avl_link
[0] == NULL
)
760 if (y
!= (struct avl_node
*) &new->avl_root
)
763 y
->avl_link
[1] = NULL
;
766 copy_error_recovery (stack
, height
, new, destroy
);
770 stack
[height
++] = (struct avl_node
*) x
;
775 y
->avl_link
[0] = NULL
;
779 y
->avl_balance
= x
->avl_balance
;
781 y
->avl_data
= x
->avl_data
;
784 y
->avl_data
= copy (x
->avl_data
, org
->avl_param
);
785 if (y
->avl_data
== NULL
)
787 y
->avl_link
[1] = NULL
;
788 copy_error_recovery (stack
, height
, new, destroy
);
793 if (x
->avl_link
[1] != NULL
)
796 new->avl_alloc
->libavl_malloc (new->avl_alloc
,
797 sizeof *y
->avl_link
[1]);
798 if (y
->avl_link
[1] == NULL
)
800 copy_error_recovery (stack
, height
, new, destroy
);
809 y
->avl_link
[1] = NULL
;
820 /* Frees storage allocated for |tree|.
821 If |destroy != NULL|, applies it to each data item in inorder. */
823 avl_destroy (struct avl_table
*tree
, avl_item_func
*destroy
)
825 struct avl_node
*p
, *q
;
827 assert (tree
!= NULL
);
829 for (p
= tree
->avl_root
; p
!= NULL
; p
= q
)
830 if (p
->avl_link
[0] == NULL
)
833 if (destroy
!= NULL
&& p
->avl_data
!= NULL
)
834 destroy (p
->avl_data
, tree
->avl_param
);
835 tree
->avl_alloc
->libavl_free (tree
->avl_alloc
, p
);
840 p
->avl_link
[0] = q
->avl_link
[1];
844 tree
->avl_alloc
->libavl_free (tree
->avl_alloc
, tree
);
847 /* Allocates |size| bytes of space using |malloc()|.
848 Returns a null pointer if allocation fails. */
850 avl_malloc (struct libavl_allocator
*allocator
, size_t size
)
852 assert (allocator
!= NULL
&& size
> 0);
853 return malloc (size
);
858 avl_free (struct libavl_allocator
*allocator
, void *block
)
860 assert (allocator
!= NULL
&& block
!= NULL
);
864 /* Default memory allocator that uses |malloc()| and |free()|. */
865 struct libavl_allocator avl_allocator_default
=
874 /* Asserts that |avl_insert()| succeeds at inserting |item| into |table|. */
876 (avl_assert_insert
) (struct avl_table
*table
, void *item
)
878 void **p
= avl_probe (table
, item
);
879 assert (p
!= NULL
&& *p
== item
);
882 /* Asserts that |avl_delete()| really removes |item| from |table|,
883 and returns the removed item. */
885 (avl_assert_delete
) (struct avl_table
*table
, void *item
)
887 void *p
= avl_delete (table
, item
);