13 return (
void *)((uintptr_t)e + t->off);
22static inline cstl_rbtree_color_t * BN_COLOR(
43 __cstl_bintree_child_func_t *
const l,
44 __cstl_bintree_child_func_t *
const r)
54 if (y != NULL && *BN_COLOR(y) == CSTL_RBTREE_COLOR_R) {
62 *BN_COLOR(x->p) = CSTL_RBTREE_COLOR_B;
63 *BN_COLOR(y) = CSTL_RBTREE_COLOR_B;
64 *BN_COLOR(x->p->p) = CSTL_RBTREE_COLOR_R;
77 __cstl_bintree_rotate(t, x, l, r);
90 *BN_COLOR(x->p) = CSTL_RBTREE_COLOR_B;
91 *BN_COLOR(x->p->p) = CSTL_RBTREE_COLOR_R;
92 __cstl_bintree_rotate(t, x->p->p, r, l);
99 void *
const e,
void *
const p)
108 n->c = CSTL_RBTREE_COLOR_R;
116 while (x->p != NULL && *BN_COLOR(x->p) == CSTL_RBTREE_COLOR_R) {
123 if (x->p == x->p->p->l) {
124 x = cstl_rbtree_fix_insertion(
126 __cstl_bintree_left, __cstl_bintree_right);
128 x = cstl_rbtree_fix_insertion(
130 __cstl_bintree_right, __cstl_bintree_left);
134 *BN_COLOR(t->t.root) = CSTL_RBTREE_COLOR_B;
149 __cstl_bintree_child_func_t *
const l,
150 __cstl_bintree_child_func_t *
const r)
164 if (*BN_COLOR(w) == CSTL_RBTREE_COLOR_R) {
173 *BN_COLOR(w) = CSTL_RBTREE_COLOR_B;
174 *BN_COLOR(x->p) = CSTL_RBTREE_COLOR_R;
175 __cstl_bintree_rotate(t, x->p, l, r);
183 if ((*l(w) == NULL || *BN_COLOR(*l(w)) == CSTL_RBTREE_COLOR_B)
184 && (*r(w) == NULL || *BN_COLOR(*r(w)) == CSTL_RBTREE_COLOR_B)) {
186 *BN_COLOR(w) = CSTL_RBTREE_COLOR_R;
194 if (*r(w) == NULL || *BN_COLOR(*r(w)) == CSTL_RBTREE_COLOR_B) {
203 *BN_COLOR(*l(w)) = CSTL_RBTREE_COLOR_B;
204 *BN_COLOR(w) = CSTL_RBTREE_COLOR_R;
205 __cstl_bintree_rotate(t, w, r, l);
221 *BN_COLOR(w) = *BN_COLOR(x->p);
222 *BN_COLOR(x->p) = CSTL_RBTREE_COLOR_B;
223 *BN_COLOR(*r(w)) = CSTL_RBTREE_COLOR_B;
224 __cstl_bintree_rotate(t, x->p, l, r);
238void __cstl_rbtree_erase(
struct cstl_rbtree *
const t,
242 __cstl_bintree_erase(&t->t, &n->n);
250 const cstl_rbtree_color_t c = *BN_COLOR(y);
267 if (c == CSTL_RBTREE_COLOR_B) {
275 assert(n->n.l == NULL || n->n.r == NULL);
282 if (n->n.l != NULL) {
284 }
else if (n->n.r != NULL) {
290 *BN_COLOR(x) = CSTL_RBTREE_COLOR_B;
297 assert(x->p == n->n.p);
306 while (x->p != NULL && *BN_COLOR(x) == CSTL_RBTREE_COLOR_B) {
307 if (x == x->p->l || (x == &_x.n && x->p->l == NULL)) {
308 x = cstl_rbtree_fix_deletion(
310 __cstl_bintree_left, __cstl_bintree_right);
312 x = cstl_rbtree_fix_deletion(
314 __cstl_bintree_right, __cstl_bintree_left);
323 *BN_COLOR(x) = CSTL_RBTREE_COLOR_B;
331 __cstl_rbtree_erase(t, __cstl_rbtree_node(t, p));
347static int cmp_integer(
const void *
const a,
const void *
const b,
351 return ((
struct integer *)a)->v - ((
struct integer *)b)->v;
361static int __cstl_rbtree_verify(
const void *
const elem,
369 &((
const struct integer *)elem)->n.n;
373 if (*BN_COLOR(bn) == CSTL_RBTREE_COLOR_R) {
374 ck_assert(bn->l == NULL
375 || *BN_COLOR(bn->l) == CSTL_RBTREE_COLOR_B);
376 ck_assert(bn->r == NULL
377 || *BN_COLOR(bn->r) == CSTL_RBTREE_COLOR_B);
381 ck_assert_int_lt(__cstl_bintree_cmp(t, bn->l, bn), 0);
384 ck_assert_int_ge(__cstl_bintree_cmp(t, bn->r, bn), 0);
387 if (bn->l == NULL && bn->r == NULL) {
391 for (h = 0, n = bn; n != NULL; n = n->p) {
392 if (*BN_COLOR(n) == CSTL_RBTREE_COLOR_B) {
397 ck_assert(bh == 0 || h == bh);
405static void cstl_rbtree_verify(
const struct cstl_rbtree *
const t)
407 if (t->t.root != NULL) {
412 ck_assert_uint_le(max, 2 * min);
415 t, __cstl_rbtree_verify, (
void *)&t->t,
420static void __test_cstl_rbtree_free(
void *
const p,
void *
const x)
426static void __test__cstl_rbtree_fill(
struct cstl_rbtree *
const t,
431 for (i = 0; i < n; i++) {
432 struct integer *
const in = malloc(
sizeof(*in));
442 static const size_t n = 100;
446 __test__cstl_rbtree_fill(&t, n);
447 cstl_rbtree_verify(&t);
452START_TEST(random_fill)
454 static const size_t n = 100;
459 for (i = 0; i < n; i++) {
460 struct integer *
const in = malloc(
sizeof(*in));
470 cstl_rbtree_verify(&t);
475START_TEST(random_empty)
477 static const size_t n = 100;
482 __test__cstl_rbtree_fill(&t, n);
485 struct integer _in, * in;
494 cstl_rbtree_verify(&t);
498 ck_assert_ptr_null(t.t.root);
503Suite * rbtree_suite(
void)
505 Suite *
const s = suite_create(
"rbtree");
509 tc = tcase_create(
"rbtree");
510 tcase_add_test(tc, init);
511 tcase_add_test(tc, fill);
512 tcase_add_test(tc, random_fill);
513 tcase_add_test(tc, random_empty);
515 suite_add_tcase(s, tc);
void cstl_bintree_insert(struct cstl_bintree *bt, void *e, void *p)
Insert a new object into the tree.
cstl_bintree_visit_order_t
Enumeration indicating the order in which a tree element is being visited during cstl_bintree_foreach...
@ CSTL_BINTREE_VISIT_ORDER_LEAF
The only visit to an element that has no children.
@ CSTL_BINTREE_VISIT_ORDER_MID
The second visit to an element, after its first child has/would have been visited.
@ CSTL_BINTREE_FOREACH_DIR_FWD
Each element in the tree is visited from left-to-right.
static int cstl_rbtree_foreach(const struct cstl_rbtree *const t, cstl_bintree_const_visit_func_t *const visit, void *const priv, const cstl_bintree_foreach_dir_t dir)
Visit each element in a tree, calling a user-defined function for each visit.
void cstl_rbtree_insert(struct cstl_rbtree *const t, void *const e, void *const p)
Insert a new object into the tree.
static const void * cstl_rbtree_find(const struct cstl_rbtree *const t, const void *const e, const void **const p)
Find an element within a tree.
static void cstl_rbtree_height(const struct cstl_rbtree *const t, size_t *const min, size_t *const max)
Determine the maximum and minimum heights of a tree.
static void cstl_rbtree_clear(struct cstl_rbtree *const t, cstl_xtor_func_t *const clr, void *const priv)
Remove all elements from the tree.
static size_t cstl_rbtree_size(const struct cstl_rbtree *const t)
Get the number of objects in the tree.
void * cstl_rbtree_erase(struct cstl_rbtree *const t, const void *const _p)
Remove an element from the tree.
#define DECLARE_CSTL_RBTREE(NAME, TYPE, MEMB, CMP, PRIV)
(Statically) declare and initialize a red-black tree
Node to anchor an element within a binary tree.
Node to anchor an element within a red-black tree.