libcdsb/src/set/base.c

99 lines
2.3 KiB
C
Raw Normal View History

2022-06-06 11:23:33 +03:00
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "../../include/set.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;
}
}
}
/*#####################################################################################################################*/
void vset_init(vtype_set* x, vtype t) {
x->root = rbnode_empty;
x->type = t;
}
void vset_free(vtype_set* x) {
rbnode_t* t;
rbnode_t* c;
while (!rbnode_is_empty(x->root)) {
if (!rbnode_is_empty(c->left)) {
c = c->left;
} else if (!rbnode_is_empty(c->right)) {
c = c->right;
} else if (!rbnode_is_root(c)) {
vnode_free(&c->value, x->type);
t = c;
c = c->parent;
if (t == c->left) c->left = rbnode_empty;
else c->right = rbnode_empty;
free(t);
} else {
vnode_free(&c->value, x->type);
x->root = rbnode_empty;
}
}
x->type = 0;
}
size_t vset_size(const vtype_set* x) {
size_t n;
rbiter_t i;
n = 0;
if (rbiter_init(&i, &x->root, 0)) {
while (!rbnode_is_empty(rbiter_next(&i)))
++n;
}
return n;
}
int vset_compare(const vtype_set* s0, const vtype_set* s1) {
rbiter_t iter[2];
if (s0 == s1) return 0;
if (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);
} else return s0->type < s1->type ? -1 : 1;
}