99 lines
2.3 KiB
C
99 lines
2.3 KiB
C
|
|
/* 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;
|
||
|
|
}
|