Archived
1
0
Fork 0

rbtree.c: killed some dragons

This commit is contained in:
Henrik Hautakoski 2010-05-18 08:05:59 +02:00 committed by Henrik Hautakoski
parent 319b76216b
commit 6fea192c60

View file

@ -197,8 +197,6 @@ int rbtree_insert(rbtree *tree, uint key, void *data) {
unsigned char dir = 0, dir2, last, inserted = 0; unsigned char dir = 0, dir2, last, inserted = 0;
/* somewhere in here, there should be dragons */
if (tree->root == NULL) { if (tree->root == NULL) {
tree->root = node_alloc(key, data); tree->root = node_alloc(key, data);
if (tree->root == NULL) if (tree->root == NULL)
@ -209,6 +207,8 @@ int rbtree_insert(rbtree *tree, uint key, void *data) {
t = &head; t = &head;
g = p = NULL; g = p = NULL;
q = t->child[1] = tree->root; q = t->child[1] = tree->root;
/* somewhere in here, there should be dragons */
for(;;) { for(;;) {
if (q == NULL) { if (q == NULL) {
@ -279,7 +279,7 @@ void* rbtree_delete(rbtree *tree, uint key) {
g = p = NULL; g = p = NULL;
q->child[1] = tree->root; q->child[1] = tree->root;
/* more dragons, TODO: reduce indentation */ /* more dragons (killed some of them though) */
while(q->child[dir] != NULL) { while(q->child[dir] != NULL) {
last = dir; last = dir;
@ -291,31 +291,32 @@ void* rbtree_delete(rbtree *tree, uint key) {
if (q->key == key) if (q->key == key)
f = q; f = q;
if (!is_red(q) && !is_red(q->child[dir])) { if (is_red(q) || is_red(q->child[dir]))
if (is_red(q->child[!dir])) continue;
p = p->child[last] = rotate_single(q, dir);
else if (!is_red(q->child[!dir])) { if (is_red(q->child[!dir])) {
s = p->child[!last]; p = p->child[last] = rotate_single(q, dir);
} else {
s = p->child[!last];
if (s != NULL) { if (s == NULL)
/* swap color if both child's are black */ continue;
if (!is_red(s->child[!last]) && !is_red(s->child[last])) {
p->color = RB_BLACK; if (!is_red(s->child[!last]) && !is_red(s->child[last])) {
s->color = q->color = RB_RED; p->color = RB_BLACK;
} else { s->color = q->color = RB_RED;
dir2 = (g->child[1] == p); } else {
dir2 = (g->child[1] == p);
if (is_red(s->child[last])) if (is_red(s->child[last]))
g->child[dir2] = rotate_double(p, last); g->child[dir2] = rotate_double(p, last);
else if (is_red(s->child[!last])) else if (is_red(s->child[!last]))
g->child[dir2] = rotate_single(p, last); g->child[dir2] = rotate_single(p, last);
q->color = g->child[dir2]->color = RB_RED; q->color = g->child[dir2]->color = RB_RED;
g->child[dir2]->child[0]->color = RB_BLACK; g->child[dir2]->child[0]->color = RB_BLACK;
g->child[dir2]->child[1]->color = RB_BLACK; g->child[dir2]->child[1]->color = RB_BLACK;
} }
}
}
} }
} }