1 /* Produced by texiweb from libavl.w. */
4 /* libavl - library for manipulation of binary trees.
5 Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc.
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 The author may be contacted at <blp@gnu.org> on the Internet, or
23 write to Ben Pfaff, Stanford University, Computer Science Dept., 353
24 Serra Mall, Stanford CA 94305, USA.
33 /* Creates and returns a new table
34 with comparison function |compare| using parameter |param|
35 and memory allocator |allocator|.
36 Returns |NULL| if memory allocation failed. */
37 struct avl_table
*avl_create(avl_comparison_func
* compare
, void *param
,
38 struct libavl_allocator
*allocator
)
40 struct avl_table
*tree
;
42 assert(compare
!= NULL
);
44 if (allocator
== NULL
)
45 allocator
= &avl_allocator_default
;
47 tree
= allocator
->libavl_malloc(allocator
, sizeof *tree
);
51 tree
->avl_root
= NULL
;
52 tree
->avl_compare
= compare
;
53 tree
->avl_param
= param
;
54 tree
->avl_alloc
= allocator
;
56 tree
->avl_generation
= 0;
61 /* Search |tree| for an item matching |item|, and return it if found.
62 Otherwise return |NULL|. */
63 void *avl_find(const struct avl_table
*tree
, const void *item
)
65 const struct avl_node
*p
;
67 assert(tree
!= NULL
&& item
!= NULL
);
68 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. */
86 void **avl_probe(struct avl_table
*tree
, void *item
)
88 struct avl_node
*y
, *z
; /* Top node to update balance factor, and parent. */
89 struct avl_node
*p
, *q
; /* Iterator, and parent. */
90 struct avl_node
*n
; /* Newly inserted node. */
91 struct avl_node
*w
; /* New root of rebalanced subtree. */
92 int dir
; /* Direction to descend. */
94 unsigned char da
[AVL_MAX_HEIGHT
]; /* Cached comparison results. */
95 int k
= 0; /* Number of cached results. */
97 assert(tree
!= NULL
&& item
!= NULL
);
99 z
= (struct avl_node
*) &tree
->avl_root
;
102 for (q
= z
, p
= y
; p
!= NULL
; q
= p
, p
= p
->avl_link
[dir
]) {
103 int cmp
= tree
->avl_compare(item
, p
->avl_data
, tree
->avl_param
);
107 if (p
->avl_balance
!= 0)
110 da
[k
++] = (unsigned char)dir
;
113 n
= q
->avl_link
[dir
] =
114 tree
->avl_alloc
->libavl_malloc(tree
->avl_alloc
, sizeof *n
);
120 n
->avl_link
[0] = n
->avl_link
[1] = NULL
;
125 for (p
= y
, k
= 0; p
!= n
; p
= p
->avl_link
[da
[k
]], k
++)
131 if (y
->avl_balance
== -2) {
132 struct avl_node
*x
= y
->avl_link
[0];
133 if (x
->avl_balance
== -1) {
135 y
->avl_link
[0] = x
->avl_link
[1];
137 x
->avl_balance
= y
->avl_balance
= 0;
139 assert(x
->avl_balance
== +1);
141 x
->avl_link
[1] = w
->avl_link
[0];
143 y
->avl_link
[0] = w
->avl_link
[1];
145 if (w
->avl_balance
== -1)
146 x
->avl_balance
= 0, y
->avl_balance
= +1;
147 else if (w
->avl_balance
== 0)
148 x
->avl_balance
= y
->avl_balance
= 0;
149 else /* |w->avl_balance == +1| */
150 x
->avl_balance
= -1, y
->avl_balance
= 0;
153 } else if (y
->avl_balance
== +2) {
154 struct avl_node
*x
= y
->avl_link
[1];
155 if (x
->avl_balance
== +1) {
157 y
->avl_link
[1] = x
->avl_link
[0];
159 x
->avl_balance
= y
->avl_balance
= 0;
161 assert(x
->avl_balance
== -1);
163 x
->avl_link
[0] = w
->avl_link
[1];
165 y
->avl_link
[1] = w
->avl_link
[0];
167 if (w
->avl_balance
== +1)
168 x
->avl_balance
= 0, y
->avl_balance
= -1;
169 else if (w
->avl_balance
== 0)
170 x
->avl_balance
= y
->avl_balance
= 0;
171 else /* |w->avl_balance == -1| */
172 x
->avl_balance
= +1, y
->avl_balance
= 0;
177 z
->avl_link
[y
!= z
->avl_link
[0]] = w
;
179 tree
->avl_generation
++;
183 /* Inserts |item| into |table|.
184 Returns |NULL| if |item| was successfully inserted
185 or if a memory allocation error occurred.
186 Otherwise, returns the duplicate item. */
187 void *avl_insert(struct avl_table
*table
, void *item
)
189 void **p
= avl_probe(table
, item
);
190 return p
== NULL
|| *p
== item
? NULL
: *p
;
193 /* Inserts |item| into |table|, replacing any duplicate item.
194 Returns |NULL| if |item| was inserted without replacing a duplicate,
195 or if a memory allocation error occurred.
196 Otherwise, returns the item that was replaced. */
197 void *avl_replace(struct avl_table
*table
, void *item
)
199 void **p
= avl_probe(table
, item
);
200 if (p
== NULL
|| *p
== item
)
209 /* Deletes from |tree| and returns an item matching |item|.
210 Returns a null pointer if no matching item found. */
211 void *avl_delete(struct avl_table
*tree
, const void *item
)
213 /* Stack of nodes. */
214 struct avl_node
*pa
[AVL_MAX_HEIGHT
]; /* Nodes. */
215 unsigned char da
[AVL_MAX_HEIGHT
]; /* |avl_link[]| indexes. */
216 int k
; /* Stack pointer. */
218 struct avl_node
*p
; /* Traverses tree to find node to delete. */
219 int cmp
; /* Result of comparison between |item| and |p|. */
223 assert(tree
!= NULL
&& item
!= NULL
);
226 p
= (struct avl_node
*) &tree
->avl_root
;
227 for (cmp
= -1; cmp
!= 0;
228 cmp
= tree
->avl_compare(item
, p
->avl_data
, tree
->avl_param
)) {
232 da
[k
++] = (unsigned char)dir
;
234 p
= p
->avl_link
[dir
];
240 if (p
->avl_link
[1] == NULL
)
241 pa
[k
- 1]->avl_link
[da
[k
- 1]] = p
->avl_link
[0];
243 struct avl_node
*r
= p
->avl_link
[1];
244 if (r
->avl_link
[0] == NULL
) {
245 r
->avl_link
[0] = p
->avl_link
[0];
246 r
->avl_balance
= p
->avl_balance
;
247 pa
[k
- 1]->avl_link
[da
[k
- 1]] = r
;
258 if (s
->avl_link
[0] == NULL
)
264 s
->avl_link
[0] = p
->avl_link
[0];
265 r
->avl_link
[0] = s
->avl_link
[1];
266 s
->avl_link
[1] = p
->avl_link
[1];
267 s
->avl_balance
= p
->avl_balance
;
269 pa
[j
- 1]->avl_link
[da
[j
- 1]] = s
;
275 tree
->avl_alloc
->libavl_free(tree
->avl_alloc
, p
);
279 struct avl_node
*y
= pa
[k
];
283 if (y
->avl_balance
== +1)
285 else if (y
->avl_balance
== +2) {
286 struct avl_node
*x
= y
->avl_link
[1];
287 if (x
->avl_balance
== -1) {
289 assert(x
->avl_balance
== -1);
291 x
->avl_link
[0] = w
->avl_link
[1];
293 y
->avl_link
[1] = w
->avl_link
[0];
295 if (w
->avl_balance
== +1)
296 x
->avl_balance
= 0, y
->avl_balance
= -1;
297 else if (w
->avl_balance
== 0)
298 x
->avl_balance
= y
->avl_balance
= 0;
299 else /* |w->avl_balance == -1| */
300 x
->avl_balance
= +1, y
->avl_balance
= 0;
302 pa
[k
- 1]->avl_link
[da
[k
- 1]] = w
;
304 y
->avl_link
[1] = x
->avl_link
[0];
306 pa
[k
- 1]->avl_link
[da
[k
- 1]] = x
;
307 if (x
->avl_balance
== 0) {
312 x
->avl_balance
= y
->avl_balance
= 0;
317 if (y
->avl_balance
== -1)
319 else if (y
->avl_balance
== -2) {
320 struct avl_node
*x
= y
->avl_link
[0];
321 if (x
->avl_balance
== +1) {
323 assert(x
->avl_balance
== +1);
325 x
->avl_link
[1] = w
->avl_link
[0];
327 y
->avl_link
[0] = w
->avl_link
[1];
329 if (w
->avl_balance
== -1)
330 x
->avl_balance
= 0, y
->avl_balance
= +1;
331 else if (w
->avl_balance
== 0)
332 x
->avl_balance
= y
->avl_balance
= 0;
333 else /* |w->avl_balance == +1| */
334 x
->avl_balance
= -1, y
->avl_balance
= 0;
336 pa
[k
- 1]->avl_link
[da
[k
- 1]] = w
;
338 y
->avl_link
[0] = x
->avl_link
[1];
340 pa
[k
- 1]->avl_link
[da
[k
- 1]] = x
;
341 if (x
->avl_balance
== 0) {
346 x
->avl_balance
= y
->avl_balance
= 0;
353 tree
->avl_generation
++;
357 /* Refreshes the stack of parent pointers in |trav|
358 and updates its generation number. */
359 static void trav_refresh(struct avl_traverser
*trav
)
361 assert(trav
!= NULL
);
363 trav
->avl_generation
= trav
->avl_table
->avl_generation
;
365 if (trav
->avl_node
!= NULL
) {
366 avl_comparison_func
*cmp
= trav
->avl_table
->avl_compare
;
367 void *param
= trav
->avl_table
->avl_param
;
368 struct avl_node
*node
= trav
->avl_node
;
371 trav
->avl_height
= 0;
372 for (i
= trav
->avl_table
->avl_root
; i
!= node
;) {
373 assert(trav
->avl_height
< AVL_MAX_HEIGHT
);
376 trav
->avl_stack
[trav
->avl_height
++] = i
;
377 i
= i
->avl_link
[cmp(node
->avl_data
, i
->avl_data
, param
) > 0];
382 /* Initializes |trav| for use with |tree|
383 and selects the null node. */
384 void avl_t_init(struct avl_traverser
*trav
, struct avl_table
*tree
)
386 trav
->avl_table
= tree
;
387 trav
->avl_node
= NULL
;
388 trav
->avl_height
= 0;
389 trav
->avl_generation
= tree
->avl_generation
;
392 /* Initializes |trav| for |tree|
393 and selects and returns a pointer to its least-valued item.
394 Returns |NULL| if |tree| contains no nodes. */
395 void *avl_t_first(struct avl_traverser
*trav
, struct avl_table
*tree
)
399 assert(tree
!= NULL
&& trav
!= NULL
);
401 trav
->avl_table
= tree
;
402 trav
->avl_height
= 0;
403 trav
->avl_generation
= tree
->avl_generation
;
407 while (x
->avl_link
[0] != NULL
) {
408 assert(trav
->avl_height
< AVL_MAX_HEIGHT
);
409 trav
->avl_stack
[trav
->avl_height
++] = x
;
414 return x
!= NULL
? x
->avl_data
: NULL
;
417 /* Initializes |trav| for |tree|
418 and selects and returns a pointer to its greatest-valued item.
419 Returns |NULL| if |tree| contains no nodes. */
420 void *avl_t_last(struct avl_traverser
*trav
, struct avl_table
*tree
)
424 assert(tree
!= NULL
&& trav
!= NULL
);
426 trav
->avl_table
= tree
;
427 trav
->avl_height
= 0;
428 trav
->avl_generation
= tree
->avl_generation
;
432 while (x
->avl_link
[1] != NULL
) {
433 assert(trav
->avl_height
< AVL_MAX_HEIGHT
);
434 trav
->avl_stack
[trav
->avl_height
++] = x
;
439 return x
!= NULL
? x
->avl_data
: NULL
;
442 /* Searches for |item| in |tree|.
443 If found, initializes |trav| to the item found and returns the item
445 If there is no matching item, initializes |trav| to the null item
446 and returns |NULL|. */
447 void *avl_t_find(struct avl_traverser
*trav
, struct avl_table
*tree
, void *item
)
449 struct avl_node
*p
, *q
;
451 assert(trav
!= NULL
&& tree
!= NULL
&& item
!= NULL
);
452 trav
->avl_table
= tree
;
453 trav
->avl_height
= 0;
454 trav
->avl_generation
= tree
->avl_generation
;
455 for (p
= tree
->avl_root
; p
!= NULL
; p
= q
) {
456 int cmp
= tree
->avl_compare(item
, p
->avl_data
, tree
->avl_param
);
462 else { /* |cmp == 0| */
468 assert(trav
->avl_height
< AVL_MAX_HEIGHT
);
469 trav
->avl_stack
[trav
->avl_height
++] = p
;
472 trav
->avl_height
= 0;
473 trav
->avl_node
= NULL
;
477 /* Attempts to insert |item| into |tree|.
478 If |item| is inserted successfully, it is returned and |trav| is
479 initialized to its location.
480 If a duplicate is found, it is returned and |trav| is initialized to
481 its location. No replacement of the item occurs.
482 If a memory allocation failure occurs, |NULL| is returned and |trav|
483 is initialized to the null item. */
484 void *avl_t_insert(struct avl_traverser
*trav
, struct avl_table
*tree
,
489 assert(trav
!= NULL
&& tree
!= NULL
&& item
!= NULL
);
491 p
= avl_probe(tree
, item
);
493 trav
->avl_table
= tree
;
494 trav
->avl_node
= ((struct avl_node
*)
495 ((char *) p
- offsetof(struct avl_node
, avl_data
)));
496 trav
->avl_generation
= tree
->avl_generation
- 1;
499 avl_t_init(trav
, tree
);
504 /* Initializes |trav| to have the same current node as |src|. */
505 void *avl_t_copy(struct avl_traverser
*trav
, const struct avl_traverser
*src
)
507 assert(trav
!= NULL
&& src
!= NULL
);
510 trav
->avl_table
= src
->avl_table
;
511 trav
->avl_node
= src
->avl_node
;
512 trav
->avl_generation
= src
->avl_generation
;
513 if (trav
->avl_generation
== trav
->avl_table
->avl_generation
) {
514 trav
->avl_height
= src
->avl_height
;
515 memcpy(trav
->avl_stack
, (const void *) src
->avl_stack
,
516 sizeof *trav
->avl_stack
* trav
->avl_height
);
520 return trav
->avl_node
!= NULL
? trav
->avl_node
->avl_data
: NULL
;
523 /* Returns the next data item in inorder
524 within the tree being traversed with |trav|,
525 or if there are no more data items returns |NULL|. */
526 void *avl_t_next(struct avl_traverser
*trav
)
530 assert(trav
!= NULL
);
532 if (trav
->avl_generation
!= trav
->avl_table
->avl_generation
)
537 return avl_t_first(trav
, trav
->avl_table
);
538 } else if (x
->avl_link
[1] != NULL
) {
539 assert(trav
->avl_height
< AVL_MAX_HEIGHT
);
540 trav
->avl_stack
[trav
->avl_height
++] = x
;
543 while (x
->avl_link
[0] != NULL
) {
544 assert(trav
->avl_height
< AVL_MAX_HEIGHT
);
545 trav
->avl_stack
[trav
->avl_height
++] = x
;
552 if (trav
->avl_height
== 0) {
553 trav
->avl_node
= NULL
;
558 x
= trav
->avl_stack
[--trav
->avl_height
];
560 while (y
== x
->avl_link
[1]);
567 /* Returns the previous data item in inorder
568 within the tree being traversed with |trav|,
569 or if there are no more data items returns |NULL|. */
570 void *avl_t_prev(struct avl_traverser
*trav
)
574 assert(trav
!= NULL
);
576 if (trav
->avl_generation
!= trav
->avl_table
->avl_generation
)
581 return avl_t_last(trav
, trav
->avl_table
);
582 } else if (x
->avl_link
[0] != NULL
) {
583 assert(trav
->avl_height
< AVL_MAX_HEIGHT
);
584 trav
->avl_stack
[trav
->avl_height
++] = x
;
587 while (x
->avl_link
[1] != NULL
) {
588 assert(trav
->avl_height
< AVL_MAX_HEIGHT
);
589 trav
->avl_stack
[trav
->avl_height
++] = x
;
596 if (trav
->avl_height
== 0) {
597 trav
->avl_node
= NULL
;
602 x
= trav
->avl_stack
[--trav
->avl_height
];
604 while (y
== x
->avl_link
[0]);
611 /* Returns |trav|'s current item. */
612 void *avl_t_cur(struct avl_traverser
*trav
)
614 assert(trav
!= NULL
);
616 return trav
->avl_node
!= NULL
? trav
->avl_node
->avl_data
: NULL
;
619 /* Replaces the current item in |trav| by |new| and returns the item replaced.
620 |trav| must not have the null item selected.
621 The new item must not upset the ordering of the tree. */
622 void *avl_t_replace(struct avl_traverser
*trav
, void *new)
626 assert(trav
!= NULL
&& trav
->avl_node
!= NULL
&& new != NULL
);
627 old
= trav
->avl_node
->avl_data
;
628 trav
->avl_node
->avl_data
= new;
632 /* Destroys |new| with |avl_destroy (new, destroy)|,
633 first setting right links of nodes in |stack| within |new|
634 to null pointers to avoid touching uninitialized data. */
636 copy_error_recovery(struct avl_node
**stack
, int height
,
637 struct avl_table
*new, avl_item_func
* destroy
)
639 assert(stack
!= NULL
&& height
>= 0 && new != NULL
);
641 for (; height
> 2; height
-= 2)
642 stack
[height
- 1]->avl_link
[1] = NULL
;
643 avl_destroy(new, destroy
);
646 /* Copies |org| to a newly created tree, which is returned.
647 If |copy != NULL|, each data item in |org| is first passed to |copy|,
648 and the return values are inserted into the tree,
649 with |NULL| return values taken as indications of failure.
650 On failure, destroys the partially created new tree,
651 applying |destroy|, if non-null, to each item in the new tree so far,
653 If |allocator != NULL|, it is used for allocation in the new tree.
654 Otherwise, the same allocator used for |org| is used. */
655 struct avl_table
*avl_copy(const struct avl_table
*org
, avl_copy_func
* copy
,
656 avl_item_func
* destroy
,
657 struct libavl_allocator
*allocator
)
659 struct avl_node
*stack
[2 * (AVL_MAX_HEIGHT
+ 1)];
662 struct avl_table
*new;
663 struct avl_node org_head
, *x
, *y
;
666 new = avl_create(org
->avl_compare
, org
->avl_param
,
667 allocator
!= NULL
? allocator
: org
->avl_alloc
);
670 new->avl_count
= org
->avl_count
;
671 if (new->avl_count
== 0)
674 org_head
.avl_link
[0] = (struct avl_node
*) org
->avl_root
;
676 y
= (struct avl_node
*) &new->avl_root
;
678 while (x
->avl_link
[0] != NULL
) {
679 assert(height
< 2 * (AVL_MAX_HEIGHT
+ 1));
682 new->avl_alloc
->libavl_malloc(new->avl_alloc
,
683 sizeof *y
->avl_link
[0]);
684 if (y
->avl_link
[0] == NULL
) {
685 if (y
!= (struct avl_node
*) &new->avl_root
) {
687 y
->avl_link
[1] = NULL
;
690 copy_error_recovery(stack
, height
, new, destroy
);
699 y
->avl_link
[0] = NULL
;
702 y
->avl_balance
= x
->avl_balance
;
704 y
->avl_data
= x
->avl_data
;
706 y
->avl_data
= copy(x
->avl_data
, org
->avl_param
);
707 if (y
->avl_data
== NULL
) {
708 y
->avl_link
[1] = NULL
;
709 copy_error_recovery(stack
, height
, new, destroy
);
714 if (x
->avl_link
[1] != NULL
) {
716 new->avl_alloc
->libavl_malloc(new->avl_alloc
,
717 sizeof *y
->avl_link
[1]);
718 if (y
->avl_link
[1] == NULL
) {
719 copy_error_recovery(stack
, height
, new, destroy
);
727 y
->avl_link
[1] = NULL
;
738 /* Frees storage allocated for |tree|.
739 If |destroy != NULL|, applies it to each data item in inorder. */
740 void avl_destroy(struct avl_table
*tree
, avl_item_func
* destroy
)
742 struct avl_node
*p
, *q
;
744 assert(tree
!= NULL
);
746 for (p
= tree
->avl_root
; p
!= NULL
; p
= q
)
747 if (p
->avl_link
[0] == NULL
) {
749 if (destroy
!= NULL
&& p
->avl_data
!= NULL
)
750 destroy(p
->avl_data
, tree
->avl_param
);
751 tree
->avl_alloc
->libavl_free(tree
->avl_alloc
, p
);
754 p
->avl_link
[0] = q
->avl_link
[1];
758 tree
->avl_alloc
->libavl_free(tree
->avl_alloc
, tree
);
761 /* Allocates |size| bytes of space using |malloc()|.
762 Returns a null pointer if allocation fails. */
763 void *avl_malloc(struct libavl_allocator
*allocator
, size_t size
)
765 assert(allocator
!= NULL
&& size
> 0);
770 void avl_free(struct libavl_allocator
*allocator
, void *block
)
772 assert(allocator
!= NULL
&& block
!= NULL
);
776 /* Default memory allocator that uses |malloc()| and |free()|. */
777 struct libavl_allocator avl_allocator_default
= {
785 /* Asserts that |avl_insert()| succeeds at inserting |item| into |table|. */
787 (avl_assert_insert
) (struct avl_table
* table
, void *item
) {
788 void **p
= avl_probe(table
, item
);
789 assert(p
!= NULL
&& *p
== item
);
792 /* Asserts that |avl_delete()| really removes |item| from |table|,
793 and returns the removed item. */
794 void *(avl_assert_delete
) (struct avl_table
* table
, void *item
) {
795 void *p
= avl_delete(table
, item
);