libdict
Data Structure C Library
Loading...
Searching...
No Matches
tree_common.c
Go to the documentation of this file.
1/*
2 * libdict - common definitions for binary search trees.
3 *
4 * Copyright (c) 2001-2014, Farooq Mela
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "tree_common.h"
29
30#include <string.h>
31#include "dict_private.h"
32
36
37typedef struct {
39} tree;
40
44
45void
46tree_node_rot_left(void* Tree, void* Node)
47{
48 tree_node* const n = Node;
49 tree_node* const nr = n->rlink;
50 ASSERT(nr != NULL);
51 if ((n->rlink = nr->llink) != NULL)
52 n->rlink->parent = n;
53 nr->llink = n;
54
55 tree_node* p = n->parent;
56 n->parent = nr;
57 nr->parent = p;
58 *(p == NULL ? &((tree*)Tree)->root : p->llink == n ? &p->llink : &p->rlink) = nr;
59}
60
61void
62tree_node_rot_right(void* Tree, void* Node)
63{
64 tree_node* const n = Node;
65 tree_node* const nl = n->llink;
66 ASSERT(nl != NULL);
67 if ((n->llink = nl->rlink) != NULL)
68 n->llink->parent = n;
69 nl->rlink = n;
70
71 tree_node* const p = n->parent;
72 n->parent = nl;
73 nl->parent = p;
74 *(p == NULL ? &((tree*)Tree)->root : p->llink == n ? &p->llink : &p->rlink) = nl;
75}
76
77void*
78tree_node_prev(void* Node)
79{
80 tree_node* node = Node;
81 if (node->llink)
82 return tree_node_max(node->llink);
83 tree_node* parent = node->parent;
84 while (parent && parent->llink == node) {
85 node = parent;
86 parent = parent->parent;
87 }
88 return parent;
89}
90
91void*
92tree_node_next(void* Node)
93{
94 tree_node* node = Node;
95 if (node->rlink)
96 return tree_node_min(node->rlink);
97 tree_node* parent = node->parent;
98 while (parent && parent->rlink == node) {
99 node = parent;
100 parent = parent->parent;
101 }
102 return parent;
103}
104
105void*
106tree_node_min(void* Node)
107{
108 tree_node* node = Node;
109 if (!node)
110 return NULL;
111 while (node->llink)
112 node = node->llink;
113 return node;
114}
115
116void*
117tree_node_max(void* Node)
118{
119 tree_node* node = Node;
120 if (!node)
121 return NULL;
122 while (node->rlink)
123 node = node->rlink;
124 return node;
125}
126
127void*
128tree_search_node(void* Tree, const void* key)
129{
130 tree* t = Tree;
131 for (tree_node* node = t->root; node;) {
132 const int cmp = t->cmp_func(key, node->key);
133 if (cmp < 0)
134 node = node->llink;
135 else if (cmp)
136 node = node->rlink;
137 else
138 return node;
139 }
140 return NULL;
141}
142
143void**
144tree_search(void* Tree, const void* key)
145{
146 tree_node* node = tree_search_node(Tree, key);
147 return node ? &node->datum : NULL;
148}
149
150void*
151tree_search_le_node(void* Tree, const void* key)
152{
153 tree* t = Tree;
154 tree_node* node = t->root, *ret = NULL;
155 while (node) {
156 const int cmp = t->cmp_func(key, node->key);
157 if (cmp == 0)
158 return node;
159 if (cmp < 0) {
160 node = node->llink;
161 } else {
162 ret = node;
163 node = node->rlink;
164 }
165 }
166 return ret;
167}
168
169void**
170tree_search_le(void* Tree, const void* key)
171{
172 tree_node* node = tree_search_le_node(Tree, key);
173 return node ? &node->datum : NULL;
174}
175
176void*
177tree_search_lt_node(void* Tree, const void* key)
178{
179 tree* t = Tree;
180 tree_node* node = t->root, *ret = NULL;
181 while (node) {
182 const int cmp = t->cmp_func(key, node->key);
183 if (cmp <= 0) {
184 node = node->llink;
185 } else {
186 ret = node;
187 node = node->rlink;
188 }
189 }
190 return ret;
191}
192
193void**
194tree_search_lt(void* Tree, const void* key)
195{
196 tree_node* node = tree_search_lt_node(Tree, key);
197 return node ? &node->datum : NULL;
198}
199
200void*
201tree_search_ge_node(void* Tree, const void* key)
202{
203 tree* t = Tree;
204 tree_node* node = t->root, *ret = NULL;
205 while (node) {
206 const int cmp = t->cmp_func(key, node->key);
207 if (cmp == 0) {
208 return node;
209 }
210 if (cmp < 0) {
211 ret = node;
212 node = node->llink;
213 } else {
214 node = node->rlink;
215 }
216 }
217 return ret;
218}
219
220void**
221tree_search_ge(void* Tree, const void* key)
222{
223 tree_node* node = tree_search_ge_node(Tree, key);
224 return node ? &node->datum : NULL;
225}
226
227void*
228tree_search_gt_node(void* Tree, const void* key)
229{
230 tree* t = Tree;
231 tree_node* node = t->root, *ret = NULL;
232 while (node) {
233 const int cmp = t->cmp_func(key, node->key);
234 if (cmp < 0) {
235 ret = node;
236 node = node->llink;
237 } else {
238 node = node->rlink;
239 }
240 }
241 return ret;
242}
243
244void**
245tree_search_gt(void* Tree, const void* key)
246{
247 tree_node* node = tree_search_gt_node(Tree, key);
248 return node ? &node->datum : NULL;
249}
250
251size_t
252tree_traverse(void* Tree, dict_visit_func visit, void* user_data)
253{
254 ASSERT(visit != NULL);
255
256 tree* t = Tree;
257 size_t count = 0;
258 if (t->root) {
259 tree_node* node = tree_node_min(t->root);
260 do {
261 ++count;
262 if (!visit(node->key, node->datum, user_data)) break;
263 node = tree_node_next(node);
264 } while (node);
265 }
266 return count;
267}
268
269bool
270tree_select(void *Tree, size_t n, const void **key, void **datum)
271{
272 tree* t = Tree;
273 if (n >= t->count) {
274 *key = NULL;
275 *datum = NULL;
276 return false;
277 }
278 tree_node* node;
279 if (n >= t->count / 2) {
280 node = tree_node_max(t->root);
281 n = t->count - 1 - n;
282 while (n--)
283 node = tree_node_prev(node);
284 } else {
285 node = tree_node_min(t->root);
286 while (n--)
287 node = tree_node_next(node);
288 }
289 *key = node->key;
290 *datum = node->datum;
291 return true;
292}
293
294size_t
295tree_count(const void* Tree)
296{
297 return ((const tree*)Tree)->count;
298}
299
300size_t
301tree_clear(void* Tree, dict_delete_func delete_func)
302{
303 tree* t = Tree;
304 const size_t count = t->count;
305
306 tree_node* node = t->root;
307 while (node) {
308 if (node->llink || node->rlink) {
309 node = node->llink ? node->llink : node->rlink;
310 continue;
311 }
312 if (delete_func) delete_func(node->key, node->datum);
313 tree_node* const parent = node->parent;
314 FREE(node);
315 *(parent ? (parent->llink == node ? &parent->llink : &parent->rlink) : &t->root) = NULL;
316 node = parent;
317 }
318 ASSERT(t->root == NULL);
319 t->count = 0;
320 return count;
321}
322
323size_t
324tree_free(void* Tree, dict_delete_func delete_func)
325{
326 const size_t count = tree_clear(Tree, delete_func);
327 FREE(Tree);
328 return count;
329}
330
331static size_t
332node_min_path_length(const tree_node* node)
333{
334 size_t l = node->llink ? node_min_path_length(node->llink) : 0;
335 size_t r = node->rlink ? node_min_path_length(node->rlink) : 0;
336 return 1 + MIN(l, r);
337}
338
339size_t
340tree_min_path_length(const void* Tree)
341{
342 const tree* t = Tree;
343 return t->root ? node_min_path_length(t->root) : 0;
344}
345
346static size_t
347node_max_path_length(const tree_node* node)
348{
349 size_t l = node->llink ? node_max_path_length(node->llink) : 0;
350 size_t r = node->rlink ? node_max_path_length(node->rlink) : 0;
351 return 1 + MAX(l, r);
352}
353
354size_t
355tree_max_path_length(const void* Tree)
356{
357 const tree* t = Tree;
358 return t->root ? node_max_path_length(t->root) : 0;
359}
360
361static size_t
362node_path_length(const tree_node* node, size_t level)
363{
364 return level
365 + (node->llink ? node_path_length(node->llink, level + 1) : 0)
366 + (node->rlink ? node_path_length(node->rlink, level + 1) : 0);
367}
368
369size_t
370tree_total_path_length(const void* Tree)
371{
372 const tree* t = Tree;
373 return t->root ? node_path_length(t->root, 1) : 0;
374}
375
376bool
377tree_iterator_valid(const void* Iterator)
378{
379 return ((const tree_iterator*)Iterator)->node != NULL;
380}
381
382void
384{
385 ((tree_iterator*)Iterator)->node = NULL;
386}
387
388void
389tree_iterator_free(void* Iterator)
390{
391 tree_iterator* iterator = Iterator;
392 iterator->node = NULL;
393 FREE(iterator);
394}
395
396bool
397tree_iterator_next(void* Iterator)
398{
399 tree_iterator* iterator = Iterator;
400 if(iterator->node) {
401 iterator->node = tree_node_next(iterator->node);
402 if(iterator->node) return true;
403 }
404 return false;
405}
406
407bool
408tree_iterator_prev(void* Iterator)
409{
410 tree_iterator* iterator = Iterator;
411 if(iterator->node) {
412 iterator->node = tree_node_prev(iterator->node);
413 if(iterator->node) return true;
414 }
415 return false;
416}
417
418bool
419tree_iterator_nextn(void* Iterator, size_t count)
420{
421 tree_iterator* iterator = Iterator;
422 while (iterator->node && count--)
423 iterator->node = tree_node_next(iterator->node);
424 return iterator->node != NULL;
425}
426
427bool
428tree_iterator_prevn(void* Iterator, size_t count)
429{
430 tree_iterator* iterator = Iterator;
431 while (iterator->node && count--)
432 iterator->node = tree_node_prev(iterator->node);
433 return iterator->node != NULL;
434}
435
436bool
437tree_iterator_first(void* Iterator)
438{
439 tree_iterator* iterator = Iterator;
440 return (iterator->node = tree_node_min(iterator->tree->root)) != NULL;
441}
442
443bool
444tree_iterator_last(void* Iterator)
445{
446 tree_iterator* iterator = Iterator;
447 return (iterator->node = tree_node_max(iterator->tree->root)) != NULL;
448}
449
450bool
451tree_iterator_search(void* Iterator, const void* key)
452{
453 tree_iterator* iterator = Iterator;
454 return (iterator->node = tree_search_node(iterator->tree, key)) != NULL;
455}
456
457bool
458tree_iterator_search_le(void* Iterator, const void* key)
459{
460 tree_iterator* iterator = Iterator;
461 return (iterator->node = tree_search_le_node(iterator->tree, key)) != NULL;
462}
463
464bool
465tree_iterator_search_lt(void* Iterator, const void* key)
466{
467 tree_iterator* iterator = Iterator;
468 return (iterator->node = tree_search_lt_node(iterator->tree, key)) != NULL;
469}
470
471bool
472tree_iterator_search_ge(void* Iterator, const void* key)
473{
474 tree_iterator* iterator = Iterator;
475 return (iterator->node = tree_search_ge_node(iterator->tree, key)) != NULL;
476}
477
478bool
479tree_iterator_search_gt(void* Iterator, const void* key)
480{
481 tree_iterator* iterator = Iterator;
482 return (iterator->node = tree_search_gt_node(iterator->tree, key)) != NULL;
483}
484
485int
486tree_iterator_compare(const void* Iterator1, const void* Iterator2)
487{
488 const tree_iterator* itor1 = Iterator1;
489 const tree_iterator* itor2 = Iterator2;
490 ASSERT(itor1->tree == itor2->tree);
491 if (!itor1->node)
492 return !itor2->node ? 0 : -1;
493 if (!itor2->node)
494 return 1;
495 return itor1->tree->cmp_func(itor1->node->key, itor2->node->key);
496}
497
498const void*
499tree_iterator_key(const void* Iterator)
500{
501 const tree_iterator* iterator = Iterator;
502 return iterator->node ? iterator->node->key : NULL;
503}
504
505void**
506tree_iterator_datum(void* Iterator)
507{
508 tree_iterator* iterator = Iterator;
509 return iterator->node ? &iterator->node->datum : NULL;
510}
void(* dict_delete_func)(void *, void *)
Definition dict.h:57
bool(* dict_visit_func)(const void *, void *, void *)
Definition dict.h:59
#define FREE(p)
#define ASSERT(expr)
#define MIN(a, b)
#define MAX(a, b)
tree_node * node
Definition tree_common.c:42
struct tree_node * parent
Definition tree_common.c:34
struct tree_node * rlink
Definition tree_common.c:34
void * datum
Definition tree_common.c:34
void * key
Definition tree_common.c:34
struct tree_node * llink
Definition tree_common.c:34
dict_compare_func cmp_func
Definition tree_common.c:38
tree_node * root
Definition tree_common.c:38
size_t count
Definition tree_common.c:38
bool tree_iterator_last(void *Iterator)
size_t tree_free(void *Tree, dict_delete_func delete_func)
void * tree_search_gt_node(void *Tree, const void *key)
void ** tree_iterator_datum(void *Iterator)
bool tree_iterator_next(void *Iterator)
void * tree_search_le_node(void *Tree, const void *key)
void * tree_node_max(void *Node)
void tree_iterator_invalidate(void *Iterator)
void ** tree_search_gt(void *Tree, const void *key)
int tree_iterator_compare(const void *Iterator1, const void *Iterator2)
void tree_node_rot_left(void *Tree, void *Node)
Definition tree_common.c:46
void * tree_search_node(void *Tree, const void *key)
bool tree_iterator_search_le(void *Iterator, const void *key)
void * tree_search_lt_node(void *Tree, const void *key)
bool tree_iterator_valid(const void *Iterator)
size_t tree_count(const void *Tree)
struct tree_node tree_node
void ** tree_search_lt(void *Tree, const void *key)
size_t tree_clear(void *Tree, dict_delete_func delete_func)
const void * tree_iterator_key(const void *Iterator)
size_t tree_min_path_length(const void *Tree)
void * tree_node_min(void *Node)
void ** tree_search(void *Tree, const void *key)
bool tree_iterator_nextn(void *Iterator, size_t count)
size_t tree_traverse(void *Tree, dict_visit_func visit, void *user_data)
size_t tree_total_path_length(const void *Tree)
bool tree_iterator_first(void *Iterator)
bool tree_select(void *Tree, size_t n, const void **key, void **datum)
void tree_iterator_free(void *Iterator)
bool tree_iterator_prevn(void *Iterator, size_t count)
bool tree_iterator_search_lt(void *Iterator, const void *key)
void * tree_node_prev(void *Node)
Definition tree_common.c:78
bool tree_iterator_search_ge(void *Iterator, const void *key)
size_t tree_max_path_length(const void *Tree)
bool tree_iterator_search_gt(void *Iterator, const void *key)
void ** tree_search_ge(void *Tree, const void *key)
void tree_node_rot_right(void *Tree, void *Node)
Definition tree_common.c:62
void ** tree_search_le(void *Tree, const void *key)
void * tree_search_ge_node(void *Tree, const void *key)
bool tree_iterator_search(void *Iterator, const void *key)
void * tree_node_next(void *Node)
Definition tree_common.c:92
bool tree_iterator_prev(void *Iterator)
#define TREE_NODE_FIELDS(node_type)
Definition tree_common.h:33
#define TREE_ITERATOR_FIELDS(tree_type, node_type)
Definition tree_common.h:54
#define TREE_FIELDS(node_type)
Definition tree_common.h:44