Refactor rbtree types
This commit is contained in:
+37
-76
@@ -4,6 +4,11 @@
|
||||
#include "../../include/set.h"
|
||||
#include "../__internal/rbtree.h"
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
hash_t vset_hash(const set_t* s) {
|
||||
return rbtree_hash(s->root, nullptr, (void*)&s->type) + VTYPE_SET;
|
||||
}
|
||||
|
||||
void vset_init(set_t* x, vtype t) {
|
||||
x->root = rbnode_empty;
|
||||
@@ -12,92 +17,48 @@ void vset_init(set_t* x, vtype t) {
|
||||
|
||||
|
||||
void vset_free(set_t* x) {
|
||||
rbnode_t* t;
|
||||
rbnode_t* c;
|
||||
|
||||
c = x->root;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
rbtree_free(x->root, nullptr, &x->type);
|
||||
|
||||
x->root = rbnode_empty;
|
||||
x->type = 0;
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
size_t vset_size(const set_t* x) {
|
||||
stack_t z = { .prev = 0, .value = x->root };
|
||||
size_t n = 0;
|
||||
rbnode_t* c;
|
||||
|
||||
if (!rbnode_is_empty(x->root)) {
|
||||
while ((c = stack_pop(&z))) {
|
||||
++n;
|
||||
if (!rbnode_is_empty(c->left))
|
||||
stack_push(&z, c->left);
|
||||
if (!rbnode_is_empty(c->right))
|
||||
stack_push(&z, c->right);
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
return rbtree_size(x->root);
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
int vset_compare(const set_t* s0, const set_t* s1) {
|
||||
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 == s1) return 0;
|
||||
if (s0->type != s1->type) return s0->type - s1->type;
|
||||
|
||||
stack_push(&z, s1->root);
|
||||
stack_push(&z, s0->root);
|
||||
|
||||
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(&z);
|
||||
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(&z); return c; }
|
||||
} else {
|
||||
stack_push(&z, c1->right);
|
||||
stack_push(&z, c0->right);
|
||||
stack_push(&z, c1->left);
|
||||
stack_push(&z, c0->left);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rbtree_compare(s0->root, s1->root, nullptr, (void*)&s0->type);
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
set_t vset_copy(const set_t* s) {
|
||||
set_t x;
|
||||
|
||||
x.type = s->type;
|
||||
x.root = rbtree_duplicate(s->root, nullptr, &x.type);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
set_t* vset_duplicate(const set_t* s) {
|
||||
set_t *x = malloc(sizeof(*x));
|
||||
|
||||
x->type = s->type;
|
||||
x->root = rbtree_duplicate(s->root, nullptr, &x->type);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void vset_copy_init(set_t* x, const set_t* s) {
|
||||
x->type = s->type;
|
||||
x->root = rbtree_duplicate(s->root, nullptr, &x->type);
|
||||
}
|
||||
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../../include/set.h"
|
||||
#include "../__internal/rbtree.h"
|
||||
|
||||
set_t vset_copy(const set_t* s) {
|
||||
|
||||
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, 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));
|
||||
|
||||
} else x.root = rbnode_empty;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
set_t* vset_duplicate(const set_t* 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, 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));
|
||||
|
||||
} else x->root = rbnode_empty;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
void vset_copy_init(set_t* x, const set_t* s) {
|
||||
|
||||
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, 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));
|
||||
|
||||
} else x->root = rbnode_empty;
|
||||
}
|
||||
Reference in New Issue
Block a user