/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "../../include/set.h" #include "../__internal/rbtree.h" 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; 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; } } x->type = 0; } size_t vset_size(const vtype_set* x) { stack_t z = { .prev = 0, .value = x->root }; size_t n = 0; rbnode_t* c; 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; } int vset_compare(const vtype_set* s0, const vtype_set* 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->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; }