libdict
Data Structure C Library
Loading...
Searching...
No Matches
sp_tree.c
Go to the documentation of this file.
1/*
2 * libdict -- splay tree implementation.
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/*
29 * cf. [Sleator and Tarjan, 1985], [Tarjan 1985], [Tarjan 1983]
30 *
31 * A single operation on a splay tree has a worst-case time complexity of O(N),
32 * but a series of M operations have a time complexity of O(M lg N), and thus
33 * the amortized time complexity of an operation is O(lg N). More specifically,
34 * a series of M operations on a tree with N nodes will runs in O((N+M)lg(N+M))
35 * time. Splay trees work by "splaying" a node up the tree using a series of
36 * rotations until it is the root each time it is accessed. They are much
37 * simpler to code than most balanced trees, because there is no strict
38 * requirement about maintaining a balance scheme among nodes. When inserting
39 * and searching, we simply splay the node in question up until it becomes the
40 * root of the tree.
41 *
42 * This implementation is a bottom-up, move-to-root splay tree.
43 */
44
45/* TODO: rather than splay after the fact, use the splay operation to traverse
46 * the tree during insert, search, delete, etc. */
47
48#include "sp_tree.h"
49
50#include "dict_private.h"
51#include "tree_common.h"
52
53typedef struct sp_node sp_node;
57
61
65
66static const dict_vtable sp_tree_vtable = {
67 true,
82};
83
84static const itor_vtable sp_tree_itor_vtable = {
103};
104
105static sp_node* node_new(void* key);
106static void splay(sp_tree* t, sp_node* n);
107
108sp_tree*
110{
111 ASSERT(cmp_func != NULL);
112
113 sp_tree* tree = MALLOC(sizeof(*tree));
114 if (tree) {
115 tree->root = NULL;
116 tree->count = 0;
117 tree->cmp_func = cmp_func;
118 tree->rotation_count = 0;
119 }
120 return tree;
121}
122
123dict*
125{
126 dict* dct = MALLOC(sizeof(*dct));
127 if (dct) {
128 if (!(dct->_object = sp_tree_new(cmp_func))) {
129 FREE(dct);
130 return NULL;
131 }
132 dct->_vtable = &sp_tree_vtable;
133 }
134 return dct;
135}
136
137size_t sp_tree_free(sp_tree* tree, dict_delete_func delete_func) { return tree_free(tree, delete_func); }
138size_t sp_tree_clear(sp_tree* tree, dict_delete_func delete_func) { return tree_clear(tree, delete_func); }
139
140static void
141splay(sp_tree* t, sp_node* n)
142{
143 unsigned rotations = 0;
144 for (;;) {
145 sp_node* p = n->parent;
146 if (!p)
147 break;
148
149 sp_node* pp = p->parent;
150 if (!pp) {
151 /* Parent is the root; simply rotate root left or right so that |n|
152 * becomes new root. */
153 if (p->llink == n) {
154 if ((p->llink = n->rlink) != NULL)
155 p->llink->parent = p;
156 n->rlink = p;
157 ++rotations;
158 } else {
159 if ((p->rlink = n->llink) != NULL)
160 p->rlink->parent = p;
161 n->llink = p;
162 }
163 p->parent = n;
164 t->root = n;
165 n->parent = NULL;
166 rotations += 1;
167 break;
168 }
169
170 rotations += 2;
171 sp_node* ppp = pp->parent;
172 if (p->llink == n) {
173 if (pp->llink == p) {
174 /* Rotate parent right, then node right. */
175 sp_node* const pr = p->rlink;
176 p->rlink = pp;
177 pp->parent = p;
178 if ((pp->llink = pr) != NULL)
179 pr->parent = pp;
180
181 sp_node* const nr = n->rlink;
182 n->rlink = p;
183 p->parent = n;
184 if ((p->llink = nr) != NULL)
185 nr->parent = p;
186 } else {
187 /* Rotate node right, then parent left. */
188 sp_node* const nr = n->rlink;
189 n->rlink = p;
190 p->parent = n;
191 if ((p->llink = nr) != NULL)
192 nr->parent = p;
193
194 sp_node* const nl = n->llink;
195 n->llink = pp;
196 pp->parent = n;
197 if ((pp->rlink = nl) != NULL)
198 nl->parent = pp;
199 }
200 } else {
201 if (pp->rlink == p) {
202 /* Rotate parent left, then node left. */
203 sp_node* const pl = p->llink;
204 p->llink = pp;
205 pp->parent = p;
206 if ((pp->rlink = pl) != NULL)
207 pl->parent = pp;
208
209 sp_node* const nl = n->llink;
210 n->llink = p;
211 p->parent = n;
212 if ((p->rlink = nl) != NULL)
213 nl->parent = p;
214 } else {
215 /* Rotate node left, then parent right. */
216 sp_node* const nl = n->llink;
217 n->llink = p;
218 p->parent = n;
219 if ((p->rlink = nl) != NULL)
220 nl->parent = p;
221
222 sp_node* const nr = n->rlink;
223 n->rlink = pp;
224 pp->parent = n;
225 if ((pp->llink = nr) != NULL)
226 nr->parent = pp;
227 }
228 }
229 n->parent = ppp;
230 if (ppp) {
231 if (ppp->llink == pp)
232 ppp->llink = n;
233 else
234 ppp->rlink = n;
235 } else {
236 t->root = n;
237 break;
238 }
239 }
240 t->rotation_count += rotations;
241}
242
245{
246 int cmp = 0;
247 sp_node* node = tree->root;
248 sp_node* parent = NULL;
249 while (node) {
250 cmp = tree->cmp_func(key, node->key);
251 if (cmp < 0) {
252 parent = node; node = node->llink;
253 } else if (cmp > 0) {
254 parent = node; node = node->rlink;
255 } else
256 return (dict_insert_result) { &node->datum, false };
257 }
258
259 if (!(node = node_new(key)))
260 return (dict_insert_result) { NULL, false };
261
262 if (!(node->parent = parent)) {
263 ASSERT(tree->count == 0);
264 ASSERT(tree->root == NULL);
265 tree->root = node;
266 tree->count = 1;
267 } else {
268 if (cmp < 0)
269 parent->llink = node;
270 else
271 parent->rlink = node;
272 splay(tree, node);
273 tree->count++;
274 }
275 ASSERT(tree->root == node);
276 return (dict_insert_result) { &node->datum, true };
277}
278
279void**
280sp_tree_search(sp_tree* tree, const void* key)
281{
282 sp_node* parent = NULL;
283 for (sp_node* node = tree->root; node;) {
284 parent = node;
285 const int cmp = tree->cmp_func(key, node->key);
286 if (cmp < 0)
287 node = node->llink;
288 else if (cmp)
289 node = node->rlink;
290 else {
291 splay(tree, node);
292 ASSERT(tree->root == node);
293 return &node->datum;
294 }
295 }
296 if (parent)
297 splay(tree, parent);
298 return NULL;
299}
300
301void**
303{
304 sp_node* node = tree_search_le_node(tree, key);
305 if (node) {
306 splay(tree, node);
307 ASSERT(tree->root == node);
308 return &node->datum;
309 }
310 return NULL;
311}
312
313void**
315{
316 sp_node* node = tree_search_lt_node(tree, key);
317 if (node) {
318 splay(tree, node);
319 ASSERT(tree->root == node);
320 return &node->datum;
321 }
322 return NULL;
323}
324
325void**
327{
328 sp_node* node = tree_search_ge_node(tree, key);
329 if (node) {
330 splay(tree, node);
331 ASSERT(tree->root == node);
332 return &node->datum;
333 }
334 return NULL;
335}
336
337void**
339{
340 sp_node* node = tree_search_gt_node(tree, key);
341 if (node) {
342 splay(tree, node);
343 ASSERT(tree->root == node);
344 return &node->datum;
345 }
346 return NULL;
347}
348
349static void
350remove_node(sp_tree* tree, sp_node* node)
351{
352 sp_node* out;
353 if (!node->llink || !node->rlink) {
354 out = node;
355 } else {
356 out = tree_node_min(node->rlink);
357 void* tmp;
358 SWAP(node->key, out->key, tmp);
359 SWAP(node->datum, out->datum, tmp);
360 }
361
362 sp_node* const temp = out->llink ? out->llink : out->rlink;
363 sp_node* const parent = out->parent;
364 FREE(out);
365 if (temp)
366 temp->parent = parent;
367
368 *(parent ? (parent->llink == out ? &parent->llink : &parent->rlink) : &tree->root) = temp;
369 if (parent)
370 splay(tree, parent);
371 tree->count--;
372}
373
375sp_tree_remove(sp_tree* tree, const void* key)
376{
377 sp_node* node = tree_search_node(tree, key);
378 if (!node)
379 return (dict_remove_result) { NULL, NULL, false };
380 dict_remove_result result = { node->key, node->datum, true };
381 remove_node(tree, node);
382 return result;
383}
384
385size_t sp_tree_traverse(sp_tree* tree, dict_visit_func visit, void* user_data) { return tree_traverse(tree, visit, user_data); }
386bool sp_tree_select(sp_tree* tree, size_t n, const void** key, void** datum) { return tree_select(tree, n, key, datum); }
387size_t sp_tree_count(const sp_tree* tree) { return tree_count(tree); }
391
392static sp_node*
393node_new(void* key)
394{
395 sp_node* node = MALLOC(sizeof(*node));
396 if (node) {
397 node->key = key;
398 node->datum = NULL;
399 node->parent = NULL;
400 node->llink = NULL;
401 node->rlink = NULL;
402 }
403 return node;
404}
405
406static bool
407node_verify(const sp_tree* tree, const sp_node* parent, const sp_node* node)
408{
409 if (!parent) {
410 VERIFY(tree->root == node);
411 } else {
412 VERIFY(parent->llink == node || parent->rlink == node);
413 }
414 if (node) {
415 VERIFY(node->parent == parent);
416 if (parent) {
417 if (parent->llink == node) {
418 VERIFY(tree->cmp_func(parent->key, node->key) > 0);
419 } else {
420 ASSERT(parent->rlink == node);
421 VERIFY(tree->cmp_func(parent->key, node->key) < 0);
422 }
423 }
424 if (!node_verify(tree, node, node->llink) ||
425 !node_verify(tree, node, node->rlink))
426 return false;
427 }
428 return true;
429}
430
431bool
433{
434 if (tree->root) {
435 VERIFY(tree->count > 0);
436 } else {
437 VERIFY(tree->count == 0);
438 }
439 return node_verify(tree, NULL, tree->root);
440}
441
442sp_itor*
444{
445 sp_itor* itor = MALLOC(sizeof(*itor));
446 if (itor) {
447 itor->tree = tree;
448 itor->node = NULL;
449 }
450 return itor;
451}
452
455{
456 dict_itor* itor = MALLOC(sizeof(*itor));
457 if (itor) {
458 if (!(itor->_itor = sp_itor_new(tree))) {
459 FREE(itor);
460 return NULL;
461 }
462 itor->_vtable = &sp_tree_itor_vtable;
463 }
464 return itor;
465}
466
468bool sp_itor_valid(const sp_itor* itor) { return tree_iterator_valid(itor); }
470bool sp_itor_next(sp_itor* itor) { return tree_iterator_next(itor); }
471bool sp_itor_prev(sp_itor* itor) { return tree_iterator_prev(itor); }
472bool sp_itor_nextn(sp_itor* itor, size_t count) { return tree_iterator_nextn(itor, count); }
473bool sp_itor_prevn(sp_itor* itor, size_t count) { return tree_iterator_prevn(itor, count); }
474bool sp_itor_first(sp_itor* itor) { return tree_iterator_first(itor); }
475bool sp_itor_last(sp_itor* itor) { return tree_iterator_last(itor); }
476/* TODO: use algorithm from sp_tree_search() */
477bool sp_itor_search(sp_itor* itor, const void* key) { return tree_iterator_search(itor, key); }
478bool sp_itor_search_le(sp_itor* itor, const void* key) { return tree_iterator_search_le(itor, key); }
479bool sp_itor_search_lt(sp_itor* itor, const void* key) { return tree_iterator_search_lt(itor, key); }
480bool sp_itor_search_ge(sp_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
481bool sp_itor_search_gt(sp_itor* itor, const void* key) { return tree_iterator_search_gt(itor, key); }
482const void* sp_itor_key(const sp_itor* itor) { return tree_iterator_key(itor); }
483void** sp_itor_datum(sp_itor* itor) { return tree_iterator_datum(itor); }
484
485int
486sp_itor_compare(const sp_itor* i1, const sp_itor* i2)
487{
488 return tree_iterator_compare(i1, i2);
489}
490
491bool
493{
494 if (!itor->node)
495 return false;
496 remove_node(itor->tree, itor->node);
497 itor->node = NULL;
498 return true;
499}
dict_remove_result(* dict_remove_func)(void *obj, const void *key)
Definition dict.h:90
int(* dict_compare_func)(const void *, const void *)
Definition dict.h:54
bool(* dict_select_func)(void *obj, size_t n, const void **key, void **datum)
Definition dict.h:93
void(* dict_invalidate_func)(void *itor)
Definition dict.h:117
size_t(* dict_traverse_func)(void *obj, dict_visit_func visit, void *user_data)
Definition dict.h:92
dict_insert_result(* dict_insert_func)(void *obj, void *key)
Definition dict.h:87
void(* dict_delete_func)(void *, void *)
Definition dict.h:57
int(* dict_icompare_func)(void *itor1, void *itor2)
Definition dict.h:128
bool(* dict_nextn_func)(void *itor, size_t count)
Definition dict.h:120
bool(* dict_valid_func)(const void *itor)
Definition dict.h:116
size_t(* dict_count_func)(const void *obj)
Definition dict.h:94
bool(* dict_first_func)(void *itor)
Definition dict.h:122
bool(* dict_next_func)(void *itor)
Definition dict.h:118
void *(* dict_key_func)(void *itor)
Definition dict.h:124
size_t(* dict_dfree_func)(void *obj, dict_delete_func delete_func)
Definition dict.h:85
void **(* dict_datum_func)(void *itor)
Definition dict.h:125
bool(* dict_prevn_func)(void *itor, size_t count)
Definition dict.h:121
void **(* dict_search_func)(void *obj, const void *key)
Definition dict.h:88
bool(* dict_isearch_func)(void *itor, const void *key)
Definition dict.h:126
bool(* dict_iremove_func)(void *itor)
Definition dict.h:127
bool(* dict_prev_func)(void *itor)
Definition dict.h:119
dict_itor *(* dict_inew_func)(void *obj)
Definition dict.h:84
bool(* dict_last_func)(void *itor)
Definition dict.h:123
bool(* dict_verify_func)(const void *obj)
Definition dict.h:95
bool(* dict_visit_func)(const void *, void *, void *)
Definition dict.h:59
size_t(* dict_clear_func)(void *obj, dict_delete_func delete_func)
Definition dict.h:91
void(* dict_ifree_func)(void *itor)
Definition dict.h:115
#define FREE(p)
#define ASSERT(expr)
#define VERIFY(expr)
#define MALLOC(n)
#define SWAP(a, b, v)
bool sp_itor_last(sp_itor *itor)
Definition sp_tree.c:475
dict * sp_dict_new(dict_compare_func cmp_func)
Definition sp_tree.c:124
dict_remove_result sp_tree_remove(sp_tree *tree, const void *key)
Definition sp_tree.c:375
void ** sp_itor_datum(sp_itor *itor)
Definition sp_tree.c:483
bool sp_itor_nextn(sp_itor *itor, size_t count)
Definition sp_tree.c:472
bool sp_itor_search_ge(sp_itor *itor, const void *key)
Definition sp_tree.c:480
bool sp_itor_prev(sp_itor *itor)
Definition sp_tree.c:471
dict_insert_result sp_tree_insert(sp_tree *tree, void *key)
Definition sp_tree.c:244
size_t sp_tree_clear(sp_tree *tree, dict_delete_func delete_func)
Definition sp_tree.c:138
void sp_itor_free(sp_itor *itor)
Definition sp_tree.c:467
bool sp_tree_select(sp_tree *tree, size_t n, const void **key, void **datum)
Definition sp_tree.c:386
size_t sp_tree_min_path_length(const sp_tree *tree)
Definition sp_tree.c:388
sp_itor * sp_itor_new(sp_tree *tree)
Definition sp_tree.c:443
bool sp_itor_next(sp_itor *itor)
Definition sp_tree.c:470
int sp_itor_compare(const sp_itor *i1, const sp_itor *i2)
Definition sp_tree.c:486
bool sp_itor_remove(sp_itor *itor)
Definition sp_tree.c:492
bool sp_itor_prevn(sp_itor *itor, size_t count)
Definition sp_tree.c:473
size_t sp_tree_max_path_length(const sp_tree *tree)
Definition sp_tree.c:389
void ** sp_tree_search_lt(sp_tree *tree, const void *key)
Definition sp_tree.c:314
dict_itor * sp_dict_itor_new(sp_tree *tree)
Definition sp_tree.c:454
size_t sp_tree_free(sp_tree *tree, dict_delete_func delete_func)
Definition sp_tree.c:137
size_t sp_tree_traverse(sp_tree *tree, dict_visit_func visit, void *user_data)
Definition sp_tree.c:385
void sp_itor_invalidate(sp_itor *itor)
Definition sp_tree.c:469
size_t sp_tree_count(const sp_tree *tree)
Definition sp_tree.c:387
void ** sp_tree_search_gt(sp_tree *tree, const void *key)
Definition sp_tree.c:338
void ** sp_tree_search_le(sp_tree *tree, const void *key)
Definition sp_tree.c:302
bool sp_itor_valid(const sp_itor *itor)
Definition sp_tree.c:468
bool sp_itor_search_le(sp_itor *itor, const void *key)
Definition sp_tree.c:478
bool sp_tree_verify(const sp_tree *tree)
Definition sp_tree.c:432
bool sp_itor_first(sp_itor *itor)
Definition sp_tree.c:474
size_t sp_tree_total_path_length(const sp_tree *tree)
Definition sp_tree.c:390
bool sp_itor_search_lt(sp_itor *itor, const void *key)
Definition sp_tree.c:479
const void * sp_itor_key(const sp_itor *itor)
Definition sp_tree.c:482
bool sp_itor_search_gt(sp_itor *itor, const void *key)
Definition sp_tree.c:481
sp_tree * sp_tree_new(dict_compare_func cmp_func)
Definition sp_tree.c:109
void ** sp_tree_search_ge(sp_tree *tree, const void *key)
Definition sp_tree.c:326
void ** sp_tree_search(sp_tree *tree, const void *key)
Definition sp_tree.c:280
bool sp_itor_search(sp_itor *itor, const void *key)
Definition sp_tree.c:477
void * _itor
Definition dict.h:175
const itor_vtable * _vtable
Definition dict.h:176
Definition dict.h:151
void * _object
Definition dict.h:152
const dict_vtable * _vtable
Definition dict.h:153
sp_node * node
Definition sp_tree.c:63
sp_tree * tree
Definition sp_tree.c:63
sp_node * parent
Definition sp_tree.c:55
sp_node * llink
Definition sp_tree.c:55
void * datum
Definition sp_tree.c:55
void * key
Definition sp_tree.c:55
sp_node * rlink
Definition sp_tree.c:55
sp_node * root
Definition sp_tree.c:59
size_t rotation_count
Definition sp_tree.c:59
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
size_t rotation_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_iterator_invalidate(void *Iterator)
int tree_iterator_compare(const void *Iterator1, const void *Iterator2)
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)
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)
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)
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_node(void *Tree, const void *key)
bool tree_iterator_search(void *Iterator, const void *key)
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