Merge branch 'develop' of lirent/libcdsb into master
This commit is contained in:
commit
834ab672bc
61
src/rbtree.c
61
src/rbtree.c
@ -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) {
|
||||
rbnode_t *n, hack;
|
||||
stack_t z, *bot;
|
||||
stack_t z, *cur;
|
||||
rbnode_t *n;
|
||||
|
||||
memset(&z, 0, sizeof(z));
|
||||
|
||||
if (rbnode_is_empty(*root))
|
||||
if (rbnode_is_empty(n = *root))
|
||||
return z;
|
||||
|
||||
hack.right = *root;
|
||||
n = &hack;
|
||||
while (!rbnode_is_empty(n)) {
|
||||
stack_insert(&z, n);
|
||||
n = n->left;
|
||||
}
|
||||
|
||||
for (bot = &z;;) {
|
||||
for (;;) {
|
||||
if (rbnode_is_empty(n->right)) {
|
||||
cur = z.prev;
|
||||
z.value = z.prev->value;
|
||||
z.prev = z.prev->prev;
|
||||
|
||||
if (rbnode_is_root(n->parent) || n->parent->left == n) {
|
||||
n = n->parent;
|
||||
break;
|
||||
} else n = n->parent;
|
||||
free(cur);
|
||||
|
||||
if (rbnode_is_root(n->parent) || n->parent->left == n) {
|
||||
n = n->parent;
|
||||
break;
|
||||
}
|
||||
cur = &z;
|
||||
|
||||
do {
|
||||
n = n->parent;
|
||||
} while (n->parent->right == n);
|
||||
while ((cur = cur->prev)) {
|
||||
n = cur->value;
|
||||
|
||||
n = n->parent;
|
||||
} else {
|
||||
n = n->right;
|
||||
if (!rbnode_is_empty(n->right)) {
|
||||
n = n->right;
|
||||
|
||||
while (!rbnode_is_empty(n->left))
|
||||
n = n->left;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (rbnode_is_root(n)) {
|
||||
bot = z.prev;
|
||||
z = *bot;
|
||||
|
||||
free(bot);
|
||||
|
||||
if (reverse)
|
||||
stack_reverse(&z);
|
||||
|
||||
return z;
|
||||
while (!rbnode_is_empty(n)) {
|
||||
stack_insert(cur, n);
|
||||
n = n->left;
|
||||
}
|
||||
}
|
||||
|
||||
bot = stack_insert(bot, n);
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user