/* Restore the reb-black properties after a delete */ static void rb_delete_fix(struct rbnode **rootp, struct rbnode *x) { struct rbnode *w; while (x!=*rootp && x->colour==BLACK) { if (x==x->up->left) { w=x->up->right; if (w->colour==RED) { w->colour=BLACK; x->up->colour=RED; rb_left_rotate(rootp, x->up); w=x->up->right; } if (w->left->colour==BLACK && w->right->colour==BLACK) { w->colour=RED; x=x->up; } else { if (w->right->colour == BLACK) { w->left->colour=BLACK; w->colour=RED; rb_right_rotate(rootp, w); w=x->up->right; } w->colour=x->up->colour; x->up->colour = BLACK; w->right->colour = BLACK; rb_left_rotate(rootp, x->up); x=*rootp; } } else { w=x->up->left; if (w->colour==RED) { w->colour=BLACK; x->up->colour=RED; rb_right_rotate(rootp, x->up); w=x->up->left; } if (w->right->colour==BLACK && w->left->colour==BLACK) { w->colour=RED; x=x->up; } else { if (w->left->colour == BLACK) { w->right->colour=BLACK; w->colour=RED; rb_left_rotate(rootp, w); w=x->up->left; } w->colour=x->up->colour; x->up->colour = BLACK; w->left->colour = BLACK; rb_right_rotate(rootp, x->up); x=*rootp; } } } x->colour=BLACK; }
static void rb_insert_fixup(struct rb_node **root, struct rb_node *n) { struct rb_node *uncle; while (n->p->c == 'R') { if (n->p == n->p->p->lc) { uncle = n->p->p->rc; if (uncle->c == 'R') { /* case 1 */ n->p->c = 'B'; uncle->c = 'B'; n->p->p->c = 'R'; /* pull n up to its grandpa */ n = n->p->p; } else { if (n == n->p->rc) { /* case 2 */ /* make sure n's color is RED */ n = n->p; rb_left_rotate(root, n); } n->p->c = 'B'; /* case 3 */ n->p->p->c = 'R'; rb_right_rotate(root, n->p->p); } } else { uncle = n->p->p->lc; if (uncle->c == 'R') { /* case 1 */ n->p->c = 'B'; uncle->c = 'B'; n->p->p->c = 'R'; /* pull n up to its grandpa */ n = n->p->p; } else { if (n == n->p->lc) { /* case 2 */ /* make sure n's color is RED */ n = n->p; rb_right_rotate(root, n); } n->p->c = 'B'; /* case 3 */ n->p->p->c = 'R'; rb_left_rotate(root, n->p->p); } } } (*root)->c = 'B'; }
static void rb_insert_fixup (struct rb_node **root, struct rb_node *z) { while (z->parent->color == RB_RED) if (z->parent == z->parent->parent->left) { struct rb_node *y = z->parent->parent->right; if (y->color == RB_RED) { z->parent->color = RB_BLACK; y->color = RB_BLACK; z->parent->parent->color = RB_RED; z = z->parent->parent; } else { if (z == z->parent->right) { z = z->parent; rb_left_rotate (root, z); } z->parent->color = RB_BLACK; z->parent->parent->color = RB_RED; rb_right_rotate (root, z->parent->parent); } } else { struct rb_node *y = z->parent->parent->left; if (y->color == RB_RED) { z->parent->color = RB_BLACK; y->color = RB_BLACK; z->parent->parent->color = RB_RED; z = z->parent->parent; } else { if (z == z->parent->left) { z = z->parent; rb_right_rotate (root, z); } z->parent->color = RB_BLACK; z->parent->parent->color = RB_RED; rb_left_rotate (root, z->parent->parent); } } (*root)->color = RB_BLACK; }
static rb_node_t *rb_insert_fixup(rb_tree *tree, rb_node_t *z) { while (z->parent->color == RED) { if (z->parent == z->parent->parent->left) { rb_node_t *y = z->parent->parent->right; if (y->color == RED) { z->parent->color = BLACK; y->color = BLACK; z->parent->parent->color = RED; z = z->parent->parent; } else { if (z == z->parent->right) { z = z->parent; rb_left_rotate(tree, z); } z->parent->color = BLACK; z->parent->parent->color = RED; rb_right_rotate(tree, z->parent->parent); } } else { rb_node_t *y = z->parent->parent->left; if (y->color == RED) { z->parent->color = BLACK; y->color = BLACK; z->parent->parent->color = RED; z = z->parent->parent; } else { if (z == z->parent->left) { z = z->parent; rb_right_rotate(tree, z); } z->parent->color = BLACK; z->parent->parent->color = RED; rb_left_rotate(tree, z->parent->parent); } } } tree->root->color = BLACK; return tree->root; }
static rb_node_t *rb_delete_fixup(rb_tree *tree, rb_node_t *x) { rb_node_t *w; while (x != tree->root && x->color == BLACK) { if (x == x->parent->left) { w = x->parent->right; if (w->color == RED) { w->color = BLACK; x->parent->color = RED; rb_left_rotate(tree, x->parent); w = x->parent->right; } if (w->left->color == BLACK && w->right->color == BLACK) { w->color = RED; x = x->parent; } else { if (w->right->color == BLACK) { w->left->color = BLACK; w->color = RED; rb_right_rotate(tree, w); w = x->parent->right; } w->color = x->parent->color; x->parent->color = BLACK; w->right->color = BLACK; rb_left_rotate(tree, x->parent); x = tree->root; } } else { w = x->parent->left; if (w->color == RED) { w->color = BLACK; x->parent->color = RED; rb_right_rotate(tree, x->parent); w = x->parent->left; } if (w->left->color == BLACK && w->right->color == BLACK) { w->color = RED; x = x->parent; } else { if (w->left->color == BLACK) { w->right->color = BLACK; w->color = RED; rb_left_rotate(tree, w); w = x->parent->left; } w->color = x->parent->color; x->parent->color = BLACK; w->left->color = BLACK; rb_right_rotate(tree, x->parent); x = tree->root; } } } x->color = BLACK; return tree->root; }
/* Search for and if not found and insert is true, will add a new ** node in. Returns a pointer to the new node, or the node found */ int rbinsert(const void *key, const void * high, void *object,struct rbtree *rbinfo) { struct rbnode *x,*y,*z, *tmp; const void *max; int found=0; y=RBNULL; /* points to the parent of x */ x=rbinfo->rb_root; /* walk x down the tree */ while(x!=RBNULL && found==0) { y=x; /* printf("key=%s, x->key=%s\n", key, x->key); */ if (key<x->key) x=x->left; else if (key>x->key) x=x->right; else found=1; } if (found) return RB_FALSE; if ((z=rb_alloc())==NULL) { /* Whoops, no memory */ return RB_FALSE; } z->object=object; z->high=high; z->key=key; z->max=high; z->up=y; tmp=y; max=high; while(tmp!=RBNULL) { if (max>tmp->max) tmp->max=max; else max=tmp->max; tmp=tmp->up; } if (y==RBNULL) { rbinfo->rb_root=z; } else { if (z->key<y->key) y->left=z; else y->right=z; } z->left=RBNULL; z->right=RBNULL; /* colour this new node red */ z->colour=RED; /* Having added a red node, we must now walk back up the tree balancing ** it, by a series of rotations and changing of colours */ x=z; /* While we are not at the top and our parent node is red ** N.B. Since the root node is garanteed black, then we ** are also going to stop if we are the child of the root */ while(x != rbinfo->rb_root && (x->up->colour == RED)) { /* if our parent is on the left side of our grandparent */ if (x->up == x->up->up->left) { /* get the right side of our grandparent (uncle?) */ y=x->up->up->right; if (y->colour == RED) { /* make our parent black */ x->up->colour = BLACK; /* make our uncle black */ y->colour = BLACK; /* make our grandparent red */ x->up->up->colour = RED; /* now consider our grandparent */ x=x->up->up; } else { /* if we are on the right side of our parent */ if (x == x->up->right) { /* Move up to our parent */ x=x->up; rb_left_rotate(&rbinfo->rb_root, x); } /* make our parent black */ x->up->colour = BLACK; /* make our grandparent red */ x->up->up->colour = RED; /* right rotate our grandparent */ rb_right_rotate(&rbinfo->rb_root, x->up->up); } } else { /* everything here is the same as above, but ** exchanging left for right */ y=x->up->up->left; if (y->colour == RED) { x->up->colour = BLACK; y->colour = BLACK; x->up->up->colour = RED; x=x->up->up; } else { if (x == x->up->left) { x=x->up; rb_right_rotate(&rbinfo->rb_root, x); } x->up->colour = BLACK; x->up->up->colour = RED; rb_left_rotate(&rbinfo->rb_root, x->up->up); } } } /* Set the root node black */ (rbinfo->rb_root)->colour = BLACK; return RB_TRUE; }
static void rb_delete_fixup (struct rb_node **root, struct rb_node *x, struct rb_node *parent) { struct rb_node *w; while (x != *root && x->color == RB_BLACK) { if (x == parent->left) { w = parent->right; if (w->color == RB_RED) { w->color = RB_BLACK; parent->color = RB_RED; rb_left_rotate (root, parent); w = parent->right; } if (w->left->color == RB_BLACK && w->right->color == RB_BLACK) { w->color = RB_RED; x = parent; parent = x->parent; } else { if (w->right->color == RB_BLACK) { w->left->color = RB_BLACK; w->color = RB_RED; rb_right_rotate (root, w); w = parent->right; } w->color = parent->color; parent->color = RB_BLACK; w->right->color = RB_BLACK; rb_left_rotate (root, parent); x = *root; } } else { w = parent->left; if (w->color == RB_RED) { w->color = RB_BLACK; parent->color = RB_RED; rb_right_rotate (root, parent); w = parent->left; } if (w->right->color == RB_BLACK && w->left->color == RB_BLACK) { w->color = RB_RED; x = parent; parent = x->parent; } else { if (w->left->color == RB_BLACK) { w->right->color = RB_BLACK; w->color = RB_RED; rb_left_rotate (root, w); w = parent->left; } w->color = parent->color; parent->color = RB_BLACK; w->left->color = RB_BLACK; rb_right_rotate (root, parent); x = *root; } } } x->color = RB_BLACK; }
static struct rb_node *rb_delete_fixup(struct rb_node **root, struct rb_node *n) { struct rb_node *t; while (n != *root && n->c == 'B') { if (n == n->p->lc) { t = n->p->rc; if (t->c == 'R') { /* case 1 */ t->c = 'B'; n->p->c = 'R'; rb_left_rotate(root, n->p); t = n->p->rc; } if (t->lc->c == 'B' && t->rc->c == 'B') { /* case 2 */ t->c = 'R'; n = n->p; } else { if (t->rc->c == 'B') { /* case 3 */ t->lc->c = 'B'; t->c = 'R'; rb_right_rotate(root, t); t = n->p->rc; } t->c = n->p->c; n->p->c = 'B'; t->rc->c = 'B'; rb_left_rotate(root, n->p); } } else { /* n == n->p->rc */ t = n->p->lc; if (t->c == 'R') { /* case 1 */ t->c = 'B'; n->p->c = 'R'; rb_right_rotate(root, n->p); t = n->p->lc; } if (t->lc->c == 'B' && t->rc->c == 'B') { /* case 2 */ t->c = 'R'; n = n->p; } else { if (t->lc->c == 'B') { /* case 3 */ t->rc->c = 'B'; t->c = 'R'; rb_left_rotate(root, t); t = n->p->lc; } t->c = n->p->c; n->p->c = 'B'; t->lc->c = 'B'; rb_right_rotate(root, n->p); } } } /* n is root now */ n->c = 'B'; return *root; }