static void set_root_node(qrb_tree *tree_p, qrb_node *np) { tree_p->root = np; if( np != NULL ){ np->parent = NULL; MAKE_BLACK(np); } }
static rbtree_node_t * __tree_insert (rbtree_t *T, PyObject *k, PyObject *v) { rbtree_node_t *x = T->root; rbtree_node_t *y = T->nil; int rc = 0; // Use the optimized function until we can't if (!PyString_CheckExact(k)) { T->cmp_func = rbtree_node_compare; } while (x != T->nil) { rc = COMPARE(T, k, x->key); y = x; if (rc == 0) { // force a value update // XXX: (later) validate this? Py_XDECREF(x->value); x->value = v; Py_INCREF(v); return NULL; } if (rc < 0) x = x->l; else x = x->r; } NEW(x, rbtree_node_t); x->key = k; x->value = v; x->p = y; x->l = T->nil; x->r = T->nil; MAKE_BLACK(x); T->ct++; if (y == T->nil) { T->root = x; return x; } if (rc < 0) { y->l = x; return x; } { y->r = x; return x; } }
int rbtree_init (rbtree_t *T) { NEW(T->nil, rbtree_node_t); memset(T->nil, 0, sizeof(rbtree_node_t)); MAKE_BLACK(T->nil); T->nil->l = T->nil; T->nil->r = T->nil; T->nil->p = T->nil; T->root = T->nil; T->ct = 0; T->cmp_func = rbtree_node_compare_string; T->compare = Py_None; Py_INCREF(Py_None); return 0; }
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 __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); }
static void rb_delete(qrb_tree *tree_p, qrb_node *n_p ) { qrb_node *c_p; // the single non-leaf child qrb_node *parent; tree_p->node_count --; if( tree_p->node_count == 0 ){ assert( IS_ROOT_NODE(n_p) ); givbuf(n_p); tree_p->root = NULL; return; } if( n_p->left != NULL && n_p->right != NULL ){ //fprintf(stderr,"before calling binary_tree_delete:\n"); //dump_rb_node(n_p); n_p = binary_tree_delete(n_p); //fprintf(stderr,"after calling binary_tree_delete:\n"); //dump_rb_node(n_p); } else if( IS_ROOT_NODE(n_p) ){ // we are deleting a root node with only one child if( n_p->left != NULL ){ set_root_node(tree_p,n_p->left); } else { set_root_node(tree_p,n_p->right); } givbuf(n_p); return; } assert( n_p->left == NULL || n_p->right == NULL ); if( n_p->left != NULL ) c_p = n_p->left; else c_p = n_p->right; // may be NULL // if c_p is null, then we need to keep a reference to the parent... parent=n_p->parent; replace_node(tree_p,n_p,c_p); if( IS_RED(n_p) ){ givbuf(n_p); return; } // Now we can free n_p givbuf(n_p); if( IS_RED(c_p) ){ MAKE_BLACK(c_p); return; } // Now we know the node in question is black and has no red child //assert( n_p->left != NULL && n_p->right != NULL ); // Now we know that both n_p and c_p are black rebalance(tree_p,c_p,parent); }
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); } } }
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