1
/* Ordered set data type implemented by a binary tree.
2
Copyright (C) 2006 Free Software Foundation, Inc.
3
Written by Bruno Haible <bruno@clisp.org>, 2006.
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2, or (at your option)
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software Foundation,
17
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19
/* Common code of gl_avltree_oset.c and gl_rbtree_oset.c. */
21
/* An item on the stack used for iterating across the elements. */
28
/* A stack used for iterating across the elements. */
29
typedef iterstack_item_t iterstack_t[MAXHEIGHT];
32
gl_tree_create_empty (gl_oset_implementation_t implementation,
33
gl_setelement_compar_fn compar_fn)
35
struct gl_oset_impl *set = XMALLOC (struct gl_oset_impl);
37
set->base.vtable = implementation;
38
set->base.compar_fn = compar_fn;
46
gl_tree_size (gl_oset_t set)
52
gl_tree_search (gl_oset_t set, const void *elt)
54
gl_setelement_compar_fn compar = set->base.compar_fn;
57
for (node = set->root; node != NULL; )
59
int cmp = (compar != NULL
60
? compar (node->value, elt)
61
: (node->value > elt ? 1 :
62
node->value < elt ? -1 : 0));
69
/* We have an element equal to ELT. */
76
gl_tree_search_atleast (gl_oset_t set,
77
gl_setelement_threshold_fn threshold_fn,
78
const void *threshold,
83
for (node = set->root; node != NULL; )
85
if (! threshold_fn (node->value, threshold))
89
/* We have an element >= VALUE. But we need the leftmost such
91
gl_oset_node_t found = node;
93
for (; node != NULL; )
95
if (! threshold_fn (node->value, threshold))
103
*eltp = found->value;
110
static gl_oset_node_t
111
gl_tree_search_node (gl_oset_t set, const void *elt)
113
gl_setelement_compar_fn compar = set->base.compar_fn;
116
for (node = set->root; node != NULL; )
118
int cmp = (compar != NULL
119
? compar (node->value, elt)
120
: (node->value > elt ? 1 :
121
node->value < elt ? -1 : 0));
128
/* We have an element equal to ELT. */
135
gl_tree_add (gl_oset_t set, const void *elt)
137
gl_setelement_compar_fn compar;
138
gl_oset_node_t node = set->root;
142
gl_tree_add_first (set, elt);
146
compar = set->base.compar_fn;
150
int cmp = (compar != NULL
151
? compar (node->value, elt)
152
: (node->value > elt ? 1 :
153
node->value < elt ? -1 : 0));
157
if (node->right == NULL)
159
gl_tree_add_after (set, node, elt);
166
if (node->left == NULL)
168
gl_tree_add_before (set, node, elt);
179
gl_tree_remove (gl_oset_t set, const void *elt)
181
gl_oset_node_t node = gl_tree_search_node (set, elt);
184
return gl_tree_remove_node (set, node);
190
gl_tree_oset_free (gl_oset_t set)
192
/* Iterate across all elements in post-order. */
193
gl_oset_node_t node = set->root;
195
iterstack_item_t *stack_ptr = &stack[0];
199
/* Descend on left branch. */
204
stack_ptr->node = node;
205
stack_ptr->rightp = false;
209
/* Climb up again. */
212
if (stack_ptr == &stack[0])
215
node = stack_ptr->node;
216
if (!stack_ptr->rightp)
218
/* Free the current node. */
221
/* Descend on right branch. */
222
stack_ptr->rightp = true;
230
/* --------------------- gl_oset_iterator_t Data Type --------------------- */
232
static gl_oset_iterator_t
233
gl_tree_iterator (gl_oset_t set)
235
gl_oset_iterator_t result;
238
result.vtable = set->base.vtable;
240
/* Start node is the leftmost node. */
243
while (node->left != NULL)
246
/* End point is past the rightmost node. */
258
gl_tree_iterator_next (gl_oset_iterator_t *iterator, const void **eltp)
260
if (iterator->p != iterator->q)
262
gl_oset_node_t node = (gl_oset_node_t) iterator->p;
264
/* Advance to the next node. */
265
if (node->right != NULL)
268
while (node->left != NULL)
273
while (node->parent != NULL && node->parent->right == node)
285
gl_tree_iterator_free (gl_oset_iterator_t *iterator)