104 lines
3.1 KiB
C
104 lines
3.1 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"
|
|
|
|
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;
|
|
}
|