Change iteration implementation to the stack based
This commit is contained in:
parent
8a813e877a
commit
b6a97576e4
@ -4,36 +4,6 @@
|
|||||||
#include "../../include/set.h"
|
#include "../../include/set.h"
|
||||||
#include "../__internal/rbtree.h"
|
#include "../__internal/rbtree.h"
|
||||||
|
|
||||||
/*#####################################################################################################################*/
|
|
||||||
|
|
||||||
|
|
||||||
static int tree_compare(rbiter_t* s0, rbiter_t* s1, vtype t) {
|
|
||||||
rbnode_t* p0;
|
|
||||||
rbnode_t* p1;
|
|
||||||
int cmp;
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
p0 = rbiter_next(s0);
|
|
||||||
p1 = rbiter_next(s1);
|
|
||||||
|
|
||||||
if (rbnode_is_empty(p0) || rbnode_is_empty(p1)) {
|
|
||||||
goto end_;
|
|
||||||
} else cmp = vnode_compare(&p0->value, t, &p1->value, t);
|
|
||||||
|
|
||||||
if (cmp != 0) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
p0 = rbiter_next(s0);
|
|
||||||
p1 = rbiter_next(s1);
|
|
||||||
|
|
||||||
if (rbnode_is_empty(p0) || rbnode_is_empty(p1)) {
|
|
||||||
end_:
|
|
||||||
if (p0 == p1) return cmp;
|
|
||||||
return (rbnode_is_empty(p0)) ? -1 : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*#####################################################################################################################*/
|
/*#####################################################################################################################*/
|
||||||
|
|
||||||
@ -43,10 +13,13 @@ void vset_init(vtype_set* x, vtype t) {
|
|||||||
x->type = t;
|
x->type = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void vset_free(vtype_set* x) {
|
void vset_free(vtype_set* x) {
|
||||||
rbnode_t* t;
|
rbnode_t* t;
|
||||||
rbnode_t* c;
|
rbnode_t* c;
|
||||||
|
|
||||||
|
c = x->root;
|
||||||
|
|
||||||
while (!rbnode_is_empty(x->root)) {
|
while (!rbnode_is_empty(x->root)) {
|
||||||
if (!rbnode_is_empty(c->left)) {
|
if (!rbnode_is_empty(c->left)) {
|
||||||
c = c->left;
|
c = c->left;
|
||||||
@ -71,28 +44,61 @@ void vset_free(vtype_set* x) {
|
|||||||
x->type = 0;
|
x->type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t vset_size(const vtype_set* x) {
|
size_t vset_size(const vtype_set* x) {
|
||||||
size_t n;
|
stack_t s = { .prev = 0, .value = x->root };
|
||||||
rbiter_t i;
|
size_t n = 0;
|
||||||
|
rbnode_t* c;
|
||||||
|
|
||||||
n = 0;
|
while ((c = stack_pop(&s))) {
|
||||||
|
|
||||||
if (rbiter_init(&i, &x->root, 0)) {
|
|
||||||
while (!rbnode_is_empty(rbiter_next(&i)))
|
|
||||||
++n;
|
++n;
|
||||||
|
if (!rbnode_is_empty(c->left))
|
||||||
|
stack_push(&s, c->left);
|
||||||
|
if (!rbnode_is_empty(c->right))
|
||||||
|
stack_push(&s, c->right);
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int vset_compare(const vtype_set* s0, const vtype_set* s1) {
|
int vset_compare(const vtype_set* s0, const vtype_set* s1) {
|
||||||
rbiter_t iter[2];
|
stack_t s = { .prev = 0, .value = 0 };
|
||||||
|
vtype t = s0->type;
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
if (s0 == s1) return 0;
|
if (s0 == s1 || s0->root == s1->root) return 0;
|
||||||
if (s0->type == s1->type) {
|
if (s0->type != s1->type) return s0->type - s1->type;
|
||||||
rbiter_init(iter+0, &s0->root, RBI_INORDER);
|
|
||||||
rbiter_init(iter+1, &s1->root, RBI_INORDER);
|
|
||||||
|
|
||||||
return tree_compare(iter+0, iter+1, s0->type);
|
stack_push(&s, s0->root);
|
||||||
} else return s0->type < s1->type ? -1 : 1;
|
stack_push(&s, s1->root);
|
||||||
|
|
||||||
|
for (rbnode_t *c0, *c1;;) {
|
||||||
|
c0 = stack_pop(&s);
|
||||||
|
c1 = stack_pop(&s);
|
||||||
|
|
||||||
|
if (is_null(c0)) return 0;
|
||||||
|
|
||||||
|
if (rbnode_is_empty(c0) || rbnode_is_empty(c1)) {
|
||||||
|
if (c0 != c1) {
|
||||||
|
stack_flush(&s);
|
||||||
|
return rbnode_is_empty(c0) ? -1 : 1;
|
||||||
|
}
|
||||||
|
} else if ((c = vnode_compare(c0->value, t, c1->value, t))) {
|
||||||
|
if (c0->left == c1->right) {
|
||||||
|
c = vnode_compare(c1->value, t, c0->right->value, t);
|
||||||
|
if (!c) c = vnode_compare(c1->left->value, t, c0->value, t);
|
||||||
|
} else if (c0->right == c1->left) {
|
||||||
|
c = vnode_compare(c0->value, t, c1->right->value, t);
|
||||||
|
if (!c) c = vnode_compare(c0->left->value, t, c1->value, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c) { stack_flush(&s); return c; }
|
||||||
|
} else {
|
||||||
|
stack_push(&s, c0->left);
|
||||||
|
stack_push(&s, c1->left);
|
||||||
|
stack_push(&s, c0->right);
|
||||||
|
stack_push(&s, c1->right);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user