libdict
Data Structure C Library
Loading...
Searching...
No Matches
tr_tree.c
Go to the documentation of this file.
1/*
2 * libdict -- treap 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. [Aragon and Seidel, 1996], [Knuth 1998]
30 *
31 * A treap is a randomized data structure in which each node of tree has an
32 * associated key and priority. The priority is chosen at random when the node
33 * is inserted into the tree. Each node is inserted so that the lexicographic
34 * order of the keys is preserved, and the priority of any node is less than
35 * the priority of either of its child nodes; in this way the treap is a
36 * combination of a tree and a min-heap. In this implementation, this is
37 * accomplished by first inserting the node according to lexigraphical order of
38 * keys as in a normal binary tree, and then, if needed, sifting the node
39 * upwards using a series of rotations until the heap property of the tree is
40 * restored.
41 */
42
43#include "tr_tree.h"
44
45#include <limits.h>
46#include "dict_private.h"
47#include "tree_common.h"
48
49typedef struct tr_node tr_node;
50struct tr_node {
52 uint32_t prio;
53};
54
59
63
64static const dict_vtable tr_tree_vtable = {
65 true,
80};
81
82static const itor_vtable tr_tree_itor_vtable = {
101};
102
103static tr_node* node_new(void* key);
104
105tr_tree*
107{
108 ASSERT(cmp_func != NULL);
109
110 tr_tree* tree = MALLOC(sizeof(*tree));
111 if (tree) {
112 tree->root = NULL;
113 tree->count = 0;
114 tree->cmp_func = cmp_func;
115 tree->rotation_count = 0;
116 tree->prio_func = prio_func;
117 }
118 return tree;
119}
120
121dict*
123{
124 dict* dct = MALLOC(sizeof(*dct));
125 if (dct) {
126 if (!(dct->_object = tr_tree_new(cmp_func, prio_func))) {
127 FREE(dct);
128 return NULL;
129 }
130 dct->_vtable = &tr_tree_vtable;
131 }
132 return dct;
133}
134
135size_t tr_tree_free(tr_tree* tree, dict_delete_func delete_func) { return tree_free(tree, delete_func); }
136size_t tr_tree_clear(tr_tree* tree, dict_delete_func delete_func) { return tree_clear(tree, delete_func); }
137
140{
141 int cmp = 0;
142 tr_node* node = tree->root;
143 tr_node* parent = NULL;
144 while (node) {
145 cmp = tree->cmp_func(key, node->key);
146 if (cmp < 0) {
147 parent = node; node = node->llink;
148 } else if (cmp > 0) {
149 parent = node; node = node->rlink;
150 } else
151 return (dict_insert_result) { &node->datum, false };
152 }
153
154 if (!(node = node_new(key)))
155 return (dict_insert_result) { NULL, false };
156 node->prio = tree->prio_func ? tree->prio_func(key) : dict_rand();
157
158 if (!(node->parent = parent)) {
159 ASSERT(tree->root == NULL);
160 ASSERT(tree->count == 0);
161 tree->root = node;
162 } else {
163 if (cmp < 0)
164 parent->llink = node;
165 else
166 parent->rlink = node;
167
168 unsigned rotations = 0;
169 while (parent->prio < node->prio) {
170 ++rotations;
171 if (parent->llink == node)
172 tree_node_rot_right(tree, parent);
173 else
174 tree_node_rot_left(tree, parent);
175 if (!(parent = node->parent))
176 break;
177 }
178 tree->rotation_count += rotations;
179 }
180 tree->count++;
181 return (dict_insert_result) { &node->datum, true };
182}
183
184static void
185remove_node(tr_tree* tree, tr_node* node)
186{
187 unsigned rotations = 0;
188 while (node->llink && node->rlink) {
189 ++rotations;
190 if (node->llink->prio > node->rlink->prio)
192 else
194 }
195 tree->rotation_count += rotations;
196
197 tr_node* const out = node->llink ? node->llink : node->rlink;
198 tr_node* const parent = node->parent;
199 if (out)
200 out->parent = parent;
201 *(parent ? (parent->llink == node ? &parent->llink : &parent->rlink) : &tree->root) = out;
202
203 FREE(node);
204 tree->count--;
205}
206
208tr_tree_remove(tr_tree* tree, const void* key)
209{
210 tr_node* node = tree_search_node(tree, key);
211 if (!node)
212 return (dict_remove_result) { NULL, NULL, false };
213 dict_remove_result result = { node->key, node->datum, true };
214 remove_node(tree, node);
215 return result;
216}
217
218void** tr_tree_search(tr_tree* tree, const void* key) { return tree_search(tree, key); }
219void** tr_tree_search_le(tr_tree* tree, const void* key) { return tree_search_le(tree, key); }
220void** tr_tree_search_lt(tr_tree* tree, const void* key) { return tree_search_lt(tree, key); }
221void** tr_tree_search_ge(tr_tree* tree, const void* key) { return tree_search_ge(tree, key); }
222void** tr_tree_search_gt(tr_tree* tree, const void* key) { return tree_search_gt(tree, key); }
223size_t tr_tree_traverse(tr_tree* tree, dict_visit_func visit, void* user_data) { return tree_traverse(tree, visit, user_data); }
224bool tr_tree_select(tr_tree* tree, size_t n, const void** key, void** datum) { return tree_select(tree, n, key, datum); }
225size_t tr_tree_count(const tr_tree* tree) { return tree_count(tree); }
229
230static tr_node*
231node_new(void* key)
232{
233 tr_node* node = MALLOC(sizeof(*node));
234 if (node) {
235 node->key = key;
236 node->datum = NULL;
237 node->parent = NULL;
238 node->llink = NULL;
239 node->rlink = NULL;
240 }
241 return node;
242}
243
244static bool
245node_verify(const tr_tree* tree, const tr_node* parent, const tr_node* node)
246{
247 if (!parent) {
248 VERIFY(tree->root == node);
249 } else {
250 VERIFY(parent->llink == node || parent->rlink == node);
251 }
252 if (node) {
253 VERIFY(node->parent == parent);
254 if (parent) {
255 VERIFY(node->prio <= parent->prio);
256 if (parent->llink == node) {
257 VERIFY(tree->cmp_func(parent->key, node->key) > 0);
258 } else {
259 ASSERT(parent->rlink == node);
260 VERIFY(tree->cmp_func(parent->key, node->key) < 0);
261 }
262 }
263 if (!node_verify(tree, node, node->llink) ||
264 !node_verify(tree, node, node->rlink))
265 return false;
266 }
267 return true;
268}
269
270bool
272{
273 if (tree->root) {
274 VERIFY(tree->count > 0);
275 } else {
276 VERIFY(tree->count == 0);
277 }
278 return node_verify(tree, NULL, tree->root);
279}
280
281tr_itor*
283{
284 tr_itor* itor = MALLOC(sizeof(*itor));
285 if (itor) {
286 itor->tree = tree;
287 itor->node = NULL;
288 }
289 return itor;
290}
291
294{
295 dict_itor* itor = MALLOC(sizeof(*itor));
296 if (itor) {
297 if (!(itor->_itor = tr_itor_new(tree))) {
298 FREE(itor);
299 return NULL;
300 }
301 itor->_vtable = &tr_tree_itor_vtable;
302 }
303 return itor;
304}
305
307bool tr_itor_valid(const tr_itor* itor) { return tree_iterator_valid(itor); }
309bool tr_itor_next(tr_itor* itor) { return tree_iterator_next(itor); }
310bool tr_itor_prev(tr_itor* itor) { return tree_iterator_prev(itor); }
311bool tr_itor_nextn(tr_itor* itor, size_t count) { return tree_iterator_nextn(itor, count); }
312bool tr_itor_prevn(tr_itor* itor, size_t count) { return tree_iterator_prevn(itor, count); }
313bool tr_itor_first(tr_itor* itor) { return tree_iterator_first(itor); }
314bool tr_itor_last(tr_itor* itor) { return tree_iterator_last(itor); }
315bool tr_itor_search(tr_itor* itor, const void* key) { return tree_iterator_search(itor, key); }
316bool tr_itor_search_le(tr_itor* itor, const void* key) { return tree_iterator_search_le(itor, key); }
317bool tr_itor_search_lt(tr_itor* itor, const void* key) { return tree_iterator_search_lt(itor, key); }
318bool tr_itor_search_ge(tr_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
319bool tr_itor_search_gt(tr_itor* itor, const void* key) { return tree_iterator_search_gt(itor, key); }
320const void* tr_itor_key(const tr_itor* itor) { return tree_iterator_key(itor); }
321void** tr_itor_datum(tr_itor* itor) { return tree_iterator_datum(itor); }
322int tr_itor_compare(const tr_itor* i1, const tr_itor* i2) { return tree_iterator_compare(i1, i2); }
323
324bool
326{
327 if (!it->node)
328 return false;
329 remove_node(it->tree, it->node);
330 it->node = NULL;
331 return true;
332}
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
unsigned(* dict_prio_func)(const void *)
Definition dict.h:63
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)
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
tr_node * node
Definition tr_tree.c:61
tr_tree * tree
Definition tr_tree.c:61
tr_node * parent
Definition tr_tree.c:51
void * datum
Definition tr_tree.c:51
uint32_t prio
Definition tr_tree.c:52
void * key
Definition tr_tree.c:51
tr_node * llink
Definition tr_tree.c:51
tr_node * rlink
Definition tr_tree.c:51
dict_prio_func prio_func
Definition tr_tree.c:57
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
void ** tr_itor_datum(tr_itor *itor)
Definition tr_tree.c:321
bool tr_itor_search_le(tr_itor *itor, const void *key)
Definition tr_tree.c:316
dict_itor * tr_dict_itor_new(tr_tree *tree)
Definition tr_tree.c:293
dict_remove_result tr_tree_remove(tr_tree *tree, const void *key)
Definition tr_tree.c:208
bool tr_itor_remove(tr_itor *it)
Definition tr_tree.c:325
size_t tr_tree_total_path_length(const tr_tree *tree)
Definition tr_tree.c:228
void tr_itor_invalidate(tr_itor *itor)
Definition tr_tree.c:308
tr_tree * tr_tree_new(dict_compare_func cmp_func, dict_prio_func prio_func)
Definition tr_tree.c:106
bool tr_tree_select(tr_tree *tree, size_t n, const void **key, void **datum)
Definition tr_tree.c:224
bool tr_itor_last(tr_itor *itor)
Definition tr_tree.c:314
bool tr_itor_search_lt(tr_itor *itor, const void *key)
Definition tr_tree.c:317
void ** tr_tree_search_le(tr_tree *tree, const void *key)
Definition tr_tree.c:219
bool tr_itor_nextn(tr_itor *itor, size_t count)
Definition tr_tree.c:311
size_t tr_tree_clear(tr_tree *tree, dict_delete_func delete_func)
Definition tr_tree.c:136
bool tr_itor_next(tr_itor *itor)
Definition tr_tree.c:309
size_t tr_tree_traverse(tr_tree *tree, dict_visit_func visit, void *user_data)
Definition tr_tree.c:223
size_t tr_tree_free(tr_tree *tree, dict_delete_func delete_func)
Definition tr_tree.c:135
bool tr_itor_first(tr_itor *itor)
Definition tr_tree.c:313
tr_itor * tr_itor_new(tr_tree *tree)
Definition tr_tree.c:282
bool tr_itor_prev(tr_itor *itor)
Definition tr_tree.c:310
bool tr_itor_search_ge(tr_itor *itor, const void *key)
Definition tr_tree.c:318
size_t tr_tree_min_path_length(const tr_tree *tree)
Definition tr_tree.c:226
bool tr_itor_search_gt(tr_itor *itor, const void *key)
Definition tr_tree.c:319
const void * tr_itor_key(const tr_itor *itor)
Definition tr_tree.c:320
bool tr_itor_valid(const tr_itor *itor)
Definition tr_tree.c:307
bool tr_tree_verify(const tr_tree *tree)
Definition tr_tree.c:271
bool tr_itor_prevn(tr_itor *itor, size_t count)
Definition tr_tree.c:312
void tr_itor_free(tr_itor *itor)
Definition tr_tree.c:306
dict * tr_dict_new(dict_compare_func cmp_func, dict_prio_func prio_func)
Definition tr_tree.c:122
size_t tr_tree_count(const tr_tree *tree)
Definition tr_tree.c:225
int tr_itor_compare(const tr_itor *i1, const tr_itor *i2)
Definition tr_tree.c:322
void ** tr_tree_search_lt(tr_tree *tree, const void *key)
Definition tr_tree.c:220
void ** tr_tree_search_ge(tr_tree *tree, const void *key)
Definition tr_tree.c:221
void ** tr_tree_search_gt(tr_tree *tree, const void *key)
Definition tr_tree.c:222
dict_insert_result tr_tree_insert(tr_tree *tree, void *key)
Definition tr_tree.c:139
bool tr_itor_search(tr_itor *itor, const void *key)
Definition tr_tree.c:315
size_t tr_tree_max_path_length(const tr_tree *tree)
Definition tr_tree.c:227
void ** tr_tree_search(tr_tree *tree, const void *key)
Definition tr_tree.c:218
bool tree_iterator_last(void *Iterator)
size_t tree_free(void *Tree, dict_delete_func delete_func)
void ** tree_iterator_datum(void *Iterator)
bool tree_iterator_next(void *Iterator)
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)
bool tree_iterator_valid(const void *Iterator)
size_t tree_count(const void *Tree)
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_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)
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)
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