Fix rbtree inorder iter

This commit is contained in:
Gregory Lirent 2022-08-25 21:43:31 +03:00
parent 13fe620925
commit 76ca84f72e

View File

@ -196,60 +196,41 @@ void* libcdsb_builtin_rbtree_node_create(void* v, rbnode_t* p, int c, int n) {
stack_t libcdsb_builtin_rbtree_iter_inorder(rbnode_t** root, bool reverse) { stack_t libcdsb_builtin_rbtree_iter_inorder(rbnode_t** root, bool reverse) {
rbnode_t *n, hack; stack_t z, *cur;
stack_t z, *bot; rbnode_t *n;
memset(&z, 0, sizeof(z)); memset(&z, 0, sizeof(z));
if (rbnode_is_empty(*root)) if (rbnode_is_empty(n = *root))
return z; return z;
hack.right = *root; while (!rbnode_is_empty(n)) {
n = &hack; stack_insert(&z, n);
n = n->left;
}
for (bot = &z;;) { cur = z.prev;
for (;;) { z.value = z.prev->value;
if (rbnode_is_empty(n->right)) { z.prev = z.prev->prev;
if (rbnode_is_root(n->parent) || n->parent->left == n) { free(cur);
n = n->parent;
break;
} else n = n->parent;
if (rbnode_is_root(n->parent) || n->parent->left == n) { cur = &z;
n = n->parent;
break;
}
do { while ((cur = cur->prev)) {
n = n->parent; n = cur->value;
} while (n->parent->right == n);
n = n->parent; if (!rbnode_is_empty(n->right)) {
} else { n = n->right;
n = n->right;
while (!rbnode_is_empty(n->left)) while (!rbnode_is_empty(n)) {
n = n->left; stack_insert(cur, n);
n = n->left;
break;
}
if (rbnode_is_root(n)) {
bot = z.prev;
z = *bot;
free(bot);
if (reverse)
stack_reverse(&z);
return z;
} }
} }
bot = stack_insert(bot, n);
} }
return z;
} }