diff --git a/src/set/base.c b/src/set/base.c index 141801a..23b1dd9 100644 --- a/src/set/base.c +++ b/src/set/base.c @@ -5,9 +5,6 @@ #include "../__internal/rbtree.h" -/*#####################################################################################################################*/ - - void vset_init(vtype_set* x, vtype t) { x->root = rbnode_empty; x->type = t; @@ -46,16 +43,16 @@ void vset_free(vtype_set* x) { size_t vset_size(const vtype_set* x) { - stack_t s = { .prev = 0, .value = x->root }; + stack_t z = { .prev = 0, .value = x->root }; size_t n = 0; rbnode_t* c; - while ((c = stack_pop(&s))) { + while ((c = stack_pop(&z))) { ++n; if (!rbnode_is_empty(c->left)) - stack_push(&s, c->left); + stack_push(&z, c->left); if (!rbnode_is_empty(c->right)) - stack_push(&s, c->right); + stack_push(&z, c->right); } return n; @@ -63,25 +60,23 @@ size_t vset_size(const vtype_set* x) { int vset_compare(const vtype_set* s0, const vtype_set* s1) { - stack_t s = { .prev = 0, .value = 0 }; + stack_t z = { .prev = 0, .value = 0 }; vtype t = s0->type; int c = 0; if (s0 == s1 || s0->root == s1->root) return 0; if (s0->type != s1->type) return s0->type - s1->type; - stack_push(&s, s0->root); - stack_push(&s, s1->root); + stack_push(&z, s1->root); + stack_push(&z, s0->root); - for (rbnode_t *c0, *c1;;) { - c0 = stack_pop(&s); - c1 = stack_pop(&s); - - if (is_null(c0)) return 0; + for (rbnode_t *c0, *c1;!is_null(z.value);) { + c0 = stack_pop(&z); + c1 = stack_pop(&z); if (rbnode_is_empty(c0) || rbnode_is_empty(c1)) { if (c0 != c1) { - stack_flush(&s); + stack_flush(&z); return rbnode_is_empty(c0) ? -1 : 1; } } else if ((c = vnode_compare(c0->value, t, c1->value, t))) { @@ -93,12 +88,14 @@ int vset_compare(const vtype_set* s0, const vtype_set* s1) { if (!c) c = vnode_compare(c0->left->value, t, c1->value, t); } - if (c) { stack_flush(&s); return c; } + if (c) { stack_flush(&z); return c; } } else { - stack_push(&s, c0->left); - stack_push(&s, c1->left); - stack_push(&s, c0->right); - stack_push(&s, c1->right); + stack_push(&z, c1->right); + stack_push(&z, c0->right); + stack_push(&z, c1->left); + stack_push(&z, c0->left); } } + + return 0; } diff --git a/src/set/copy.c b/src/set/copy.c index ac75e6a..07e5ef3 100644 --- a/src/set/copy.c +++ b/src/set/copy.c @@ -4,56 +4,102 @@ #include "../../include/set.h" #include "../__internal/rbtree.h" -/*#####################################################################################################################*/ - -static void copy_child(rbnode_t* x, vtype t, const rbnode_t* l, const rbnode_t* r) { - - if (!rbnode_is_empty(l)) { - x->left = rbnode_create(vnode_duplicate(&l->value, t), x, l->colored); - copy_child(x->left, t, l->left, l->right); - } else x->left = rbnode_empty; - - if (!rbnode_is_empty(r)) { - x->left = rbnode_create(vnode_duplicate(&r->value, t), x, r->colored); - copy_child(x->right, t, r->right, r->right); - } else x->right = rbnode_empty; -} - -/*#####################################################################################################################*/ - vtype_set vset_copy(const vtype_set* s) { - set_t x = { .type = s->type }; + set_t x = { .type = s->type }; + stack_t z = { .prev = 0, .value = s->root }; + vtype t = s->type; if (!rbnode_is_empty(s->root)) { - x.root = rbnode_create(vnode_duplicate(&s->root->value, s->type), rbnode_empty, 0); + x.root = rbnode_create(vnode_duplicate(&s->root->value, t), rbnode_empty, 0); + stack_push(&z, x.root); + + do { + rbnode_t *p0, *p1; + + p0 = stack_pop(&z); + p1 = stack_pop(&z); + + if (!rbnode_is_empty(p1->left)) { + p0->left = rbnode_create(vnode_duplicate(&p1->left->value, t), p0, p1->left->colored); + stack_push(&z, p1->left); + stack_push(&z, p0->left); + } + + if (!rbnode_is_empty(p1->right)) { + p0->right = rbnode_create(vnode_duplicate(&p1->right->value, t), p0, p1->right->colored); + stack_push(&z, p1->right); + stack_push(&z, p0->right); + } + + } while (!is_null(z.value)); - copy_child(x.root, s->type, s->root->left, s->root->right); } else x.root = rbnode_empty; return x; } -vtype_set* vset_duplicate(const vtype_set* s) { - set_t* x = malloc(sizeof(*x)); - x->type = s->type; +vtype_set* vset_duplicate(const vtype_set* s) { + + set_t* x = malloc(sizeof(*x)); + stack_t z = { .prev = 0, .value = s->root }; + vtype t = x->type = s->type; if (!rbnode_is_empty(s->root)) { - x->root = rbnode_create(vnode_duplicate(&s->root->value, s->type), rbnode_empty, 0); + x->root = rbnode_create(vnode_duplicate(&s->root->value, t), rbnode_empty, 0); + stack_push(&z, x->root); + + do { + rbnode_t *p0 = stack_pop(&z); + rbnode_t *p1 = stack_pop(&z); + + if (!rbnode_is_empty(p1->left)) { + p0->left = rbnode_create(vnode_duplicate(&p1->left->value, t), p0, p1->left->colored); + stack_push(&z, p1->left); + stack_push(&z, p0->left); + } + + if (!rbnode_is_empty(p1->right)) { + p0->right = rbnode_create(vnode_duplicate(&p1->right->value, t), p0, p1->right->colored); + stack_push(&z, p1->right); + stack_push(&z, p0->right); + } + + } while (!is_null(z.value)); - copy_child(x->root, s->type, s->root->left, s->root->right); } else x->root = rbnode_empty; return x; } + void vset_copy_init(vtype_set* x, const vtype_set* s) { - x->type = s->type; + + stack_t z = { .prev = 0, .value = s->root }; + vtype t = x->type = s->type; if (!rbnode_is_empty(s->root)) { - x->root = rbnode_create(vnode_duplicate(&s->root->value, s->type), rbnode_empty, 0); + x->root = rbnode_create(vnode_duplicate(&s->root->value, t), rbnode_empty, 0); + stack_push(&z, x->root); + + do { + rbnode_t *p0 = stack_pop(&z); + rbnode_t *p1 = stack_pop(&z); + + if (!rbnode_is_empty(p1->left)) { + p0->left = rbnode_create(vnode_duplicate(&p1->left->value, t), p0, p1->left->colored); + stack_push(&z, p1->left); + stack_push(&z, p0->left); + } + + if (!rbnode_is_empty(p1->right)) { + p0->right = rbnode_create(vnode_duplicate(&p1->right->value, t), p0, p1->right->colored); + stack_push(&z, p1->right); + stack_push(&z, p0->right); + } + + } while (!is_null(z.value)); - copy_child(x->root, s->type, s->root->left, s->root->right); } else x->root = rbnode_empty; } diff --git a/src/set/extra.c b/src/set/extra.c index 9acc2d1..da5bb36 100644 --- a/src/set/extra.c +++ b/src/set/extra.c @@ -4,9 +4,6 @@ #include "../../include/extra/set.h" #include "../__internal/rbtree.h" -/*#####################################################################################################################*/ - - _Bool libcdsb_vset_find(val_t* x, set_t* s, const void* v, vtype t, _Bool cut) { rbnode_t* c; int cmp; @@ -73,25 +70,21 @@ _Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { } -/*#####################################################################################################################*/ - - int libcdsb_vset_foreach(const set_t* x, void* data, int (*callback)(const void* value, vtype type, void* data)) { - stack_t s = { .prev = 0, .value = x->root }; + stack_t z = { .prev = 0, .value = x->root }; int r = 0; rbnode_t* c; if (rbnode_is_empty(x->root)) return 0; - while ((c = stack_pop(&s))) { + while ((c = stack_pop(&z))) { if ((r = callback(vnode_peek(&c->value, x->type), x->type, data))) { - stack_flush(&s); + stack_flush(&z); break; } - if (!rbnode_is_empty(c->left)) - stack_push(&s, c->left); - if (!rbnode_is_empty(c->right)) - stack_push(&s, c->right); + + if (!rbnode_is_empty(c->right)) stack_push(&z, c->right); + if (!rbnode_is_empty(c->left)) stack_push(&z, c->left); } return r;