static void __rb_del_fix(rbtree_t *T, rbtree_node_t *x) { rbtree_node_t *w; while ((x != T->root) && (COLOR(x) == BLACK)) { if (x == x->p->l) { w = x->p->r; if (COLOR(w) == RED) { MAKE_BLACK(w); MAKE_RED (x->p); __rotate_left(T, x->p); w = x->p->r; } if ((COLOR(w->l) == BLACK) && (COLOR(w->r) == BLACK)) { MAKE_RED(w); x = x->p; } else { if (COLOR(w->r) == BLACK) { MAKE_BLACK(w->l); MAKE_RED (w); __rotate_right(T, w); w = x->p->r; } w->color = COLOR(x->p); MAKE_BLACK(x->p); MAKE_BLACK(w->r); __rotate_left(T, x->p); x = T->root; break; } } else { w = x->p->l; if (COLOR(w) == RED) { MAKE_BLACK(w); MAKE_RED (x->p); __rotate_right(T, x->p); w = x->p->l; } if ((COLOR(w->l) == BLACK) && (COLOR(w->r) == BLACK)) { MAKE_RED(w); x = x->p; } else { if (COLOR(w->l) == BLACK) { MAKE_BLACK(w->r); MAKE_RED (w); __rotate_left(T, w); w = x->p->l; } w->color = COLOR(x->p); MAKE_BLACK(x->p); MAKE_BLACK(w->l); __rotate_right(T, x->p); x = T->root; break; } } } MAKE_BLACK(x); }
static void rebalance(qrb_tree *tree_p, qrb_node *n_p, qrb_node *parent) { qrb_node *s_p; // sibling int c; if( n_p != NULL && IS_ROOT_NODE(n_p) ) return; // wikipedia case 1 assert(parent!=NULL); assert( IS_BLACK(n_p) ); s_p = sibling(n_p,parent); // we have to pass the parent because n_p may be NULL if( IS_RED(s_p) ){ // wikipedia case 2 : sibling is red MAKE_RED(/*n_p->*/parent); MAKE_BLACK(s_p); if( n_p == /*n_p->*/parent->left ){ rotate_left(tree_p,s_p); } else { rotate_right(tree_p,s_p); } //assert(n_p!=NULL); s_p = sibling(n_p,parent); // has changed } if( IS_BLACK(s_p) ){ if( IS_BLACK(s_p->left) && IS_BLACK(s_p->right) ){ // sibling and its children are black if( IS_BLACK(/*n_p->*/parent) ){ // wikipedia case 3 - make the sibling red MAKE_RED(s_p); rebalance(tree_p,/*n_p->*/parent,parent->parent); return; } else { // wikipedia case 4 MAKE_BLACK(/*n_p->*/parent); MAKE_RED(s_p); return; } } // remaining cases depend on which side S is on if( s_p == /*n_p->*/ parent->right ){ // S on right - the case shown in wikipedia examples if( IS_RED(s_p->left) && IS_BLACK(s_p->right) ){ // wikipedia case 5 assert( IS_BLACK(s_p->right) ); rotate_right(tree_p,s_p->left); MAKE_RED(s_p); MAKE_BLACK(s_p->parent); // used to be s_p->left // N's sibling has changed s_p = sibling(n_p,parent); // goto case 6 } } else { // sibling is left child - mirror case if( IS_RED(s_p->right) && IS_BLACK(s_p->left) ){ // wikipedia case 5 assert( IS_BLACK(s_p->left) ); rotate_left(tree_p,s_p->right); MAKE_RED(s_p); MAKE_BLACK(s_p->parent); // used to be s_p->left // N's sibling has changed s_p = sibling(n_p,parent); // goto case 6 } } // fall-through to case 6 if( s_p == /*n_p->*/parent->right ){ // case 6 illustrated on wikipedia assert( IS_RED(s_p->right) ); rotate_left(tree_p,s_p); // exchange colors - s_p is now the parent and the old parent is now its left child c = s_p->color; s_p->color = s_p->left->color; s_p->left->color = c; MAKE_BLACK(s_p->right); } else { // case 6, mirror condition assert( IS_RED(s_p->left) ); rotate_right(tree_p,s_p); // exchange colors - s_p is now the parent and the old parent is now its left child c = s_p->color; s_p->color = s_p->right->color; s_p->right->color = c; MAKE_BLACK(s_p->left); } } }
static void __rb_insert (rbtree_t *T, PyObject *k, PyObject *v) { rbtree_node_t *x, *y; Py_INCREF(k); Py_INCREF(v); x = __tree_insert(T, k, v); if (x == NULL) { return; } MAKE_RED (x); while ((x != T->root) && (COLOR(x->p) == RED)) { if (x->p == x->p->p->l) { y = x->p->p->r; if (COLOR(y) == RED) { MAKE_BLACK(x->p); MAKE_BLACK(y); MAKE_RED (x->p->p); x = x->p->p; } else { if (x == x->p->r) { x = x->p; __rotate_left(T, x); } MAKE_BLACK(x->p); MAKE_RED (x->p->p); __rotate_right(T, x->p->p); break; } } else { y = x->p->p->l; if (COLOR(y) == RED) { MAKE_BLACK(x->p); MAKE_BLACK(y); MAKE_RED (x->p->p); x = x->p->p; } else { if (x == x->p->l) { x = x->p; __rotate_right(T, x); } MAKE_BLACK(x->p); MAKE_RED (x->p->p); __rotate_left(T, x->p->p); break; } } } MAKE_BLACK(T->root); }
qrb_node * _rb_insert_item(QSP_ARG_DECL qrb_tree* tree_p, Item *ip ) { qrb_node * x_p; qrb_node * new_node_p; qrb_node * gp_p; // grandparent qrb_node * u_p; // uncle new_node_p = (qrb_node*) getbuf(sizeof(qrb_node)); // new_node_p->key = key; new_node_p->data = ip; new_node_p->left = NULL; new_node_p->right = NULL; MAKE_RED(new_node_p); binary_tree_insert(tree_p,new_node_p); x_p = new_node_p; while( 1 ){ if( IS_ROOT_NODE(x_p) ){ // wikipedia case 1 MAKE_BLACK(x_p); return new_node_p; } if( IS_BLACK(x_p->parent) ){ // wikipedia case 2 return new_node_p; } gp_p = grandparent(x_p); assert( gp_p != NULL ); u_p = uncle(x_p); // We know the parent is red if( IS_RED(u_p) ){ // wikipedia case 3 MAKE_BLACK(x_p->parent); MAKE_BLACK(u_p); MAKE_RED(gp_p); x_p = gp_p; // loop on grandparent } else { // uncle is black if( x_p == x_p->parent->left && x_p->parent == gp_p->left ){ // wikipedia case 5, left child of a left child rotate_right(tree_p,x_p->parent); MAKE_BLACK(x_p->parent); // new uncle is old grandparent MAKE_RED(gp_p); return new_node_p; } else if( x_p == x_p->parent->right && x_p->parent == gp_p->right ){ // wikipedia case 5 mirror image rotate_left(tree_p,x_p->parent); MAKE_BLACK(x_p->parent); // new uncle is old grandparent MAKE_RED(gp_p); return new_node_p; } else { // wikipedia case 4 if( x_p == x_p->parent->right ){ // right child of left child rotate_left(tree_p,x_p); x_p = x_p->left; } else { // left child of right child rotate_right(tree_p,x_p); x_p = x_p->right; } } } } // end tail recursion loop //MAKE_BLACK( RB_TREE_ROOT(tree) ); // NOTREACHED ??? /* tree_p->node_count ++; return new_node_p; */ } // rb_insert