Beispiel #1
0
/*
 * Maintain Red-Black tree balance after inserting node x.
 *
 * The newly inserted node is always initially marked red.	That may lead to
 * a situation where a red node has a red child, which is prohibited.  We can
 * always fix the problem by a series of color changes and/or "rotations",
 * which move the problem progressively higher up in the tree.	If one of the
 * two red nodes is the root, we can always fix the problem by changing the
 * root from red to black.
 *
 * (This does not work lower down in the tree because we must also maintain
 * the invariant that every leaf has equal black-height.)
 */
static void
rb_insert_fixup(RBTree *rb, RBNode *x)
{
	/*
	 * x is always a red node.	Initially, it is the newly inserted node. Each
	 * iteration of this loop moves it higher up in the tree.
	 */
	while (x != rb->root && x->parent->color == RBRED)
	{
		/*
		 * x and x->parent are both red.  Fix depends on whether x->parent is
		 * a left or right child.  In either case, we define y to be the
		 * "uncle" of x, that is, the other child of x's grandparent.
		 *
		 * If the uncle is red, we flip the grandparent to red and its two
		 * children to black.  Then we loop around again to check whether the
		 * grandparent still has a problem.
		 *
		 * If the uncle is black, we will perform one or two "rotations" to
		 * balance the tree.  Either x or x->parent will take the
		 * grandparent's position in the tree and recolored black, and the
		 * original grandparent will be recolored red and become a child of
		 * that node. This always leaves us with a valid red-black tree, so
		 * the loop will terminate.
		 */
		if (x->parent == x->parent->parent->left)
		{
			RBNode	   *y = x->parent->parent->right;

			if (y->color == RBRED)
			{
				/* uncle is RBRED */
				x->parent->color = RBBLACK;
				y->color = RBBLACK;
				x->parent->parent->color = RBRED;

				x = x->parent->parent;
			}
			else
			{
				/* uncle is RBBLACK */
				if (x == x->parent->right)
				{
					/* make x a left child */
					x = x->parent;
					rb_rotate_left(rb, x);
				}

				/* recolor and rotate */
				x->parent->color = RBBLACK;
				x->parent->parent->color = RBRED;

				rb_rotate_right(rb, x->parent->parent);
			}
		}
		else
		{
			/* mirror image of above code */
			RBNode	   *y = x->parent->parent->left;

			if (y->color == RBRED)
			{
				/* uncle is RBRED */
				x->parent->color = RBBLACK;
				y->color = RBBLACK;
				x->parent->parent->color = RBRED;

				x = x->parent->parent;
			}
			else
			{
				/* uncle is RBBLACK */
				if (x == x->parent->left)
				{
					x = x->parent;
					rb_rotate_right(rb, x);
				}
				x->parent->color = RBBLACK;
				x->parent->parent->color = RBRED;

				rb_rotate_left(rb, x->parent->parent);
			}
		}
	}

	/*
	 * The root may already have been black; if not, the black-height of every
	 * node in the tree increases by one.
	 */
	rb->root->color = RBBLACK;
}
Beispiel #2
0
/*
 * Maintain Red-Black tree balance after deleting a black node.
 */
static void
rb_delete_fixup(RBTree *rb, RBNode *x)
{
	/*
	 * x is always a black node.  Initially, it is the former child of the
	 * deleted node.  Each iteration of this loop moves it higher up in the
	 * tree.
	 */
	while (x != rb->root && x->color == RBBLACK)
	{
		/*
		 * Left and right cases are symmetric.	Any nodes that are children of
		 * x have a black-height one less than the remainder of the nodes in
		 * the tree.  We rotate and recolor nodes to move the problem up the
		 * tree: at some stage we'll either fix the problem, or reach the root
		 * (where the black-height is allowed to decrease).
		 */
		if (x == x->parent->left)
		{
			RBNode	   *w = x->parent->right;

			if (w->color == RBRED)
			{
				w->color = RBBLACK;
				x->parent->color = RBRED;

				rb_rotate_left(rb, x->parent);
				w = x->parent->right;
			}

			if (w->left->color == RBBLACK && w->right->color == RBBLACK)
			{
				w->color = RBRED;

				x = x->parent;
			}
			else
			{
				if (w->right->color == RBBLACK)
				{
					w->left->color = RBBLACK;
					w->color = RBRED;

					rb_rotate_right(rb, w);
					w = x->parent->right;
				}
				w->color = x->parent->color;
				x->parent->color = RBBLACK;
				w->right->color = RBBLACK;

				rb_rotate_left(rb, x->parent);
				x = rb->root;	/* Arrange for loop to terminate. */
			}
		}
		else
		{
			RBNode	   *w = x->parent->left;

			if (w->color == RBRED)
			{
				w->color = RBBLACK;
				x->parent->color = RBRED;

				rb_rotate_right(rb, x->parent);
				w = x->parent->left;
			}

			if (w->right->color == RBBLACK && w->left->color == RBBLACK)
			{
				w->color = RBRED;

				x = x->parent;
			}
			else
			{
				if (w->left->color == RBBLACK)
				{
					w->right->color = RBBLACK;
					w->color = RBRED;

					rb_rotate_left(rb, w);
					w = x->parent->left;
				}
				w->color = x->parent->color;
				x->parent->color = RBBLACK;
				w->left->color = RBBLACK;

				rb_rotate_right(rb, x->parent);
				x = rb->root;	/* Arrange for loop to terminate. */
			}
		}
	}
	x->color = RBBLACK;
}
Beispiel #3
0
void
rb_rebalance (rb_node_t * node, rb_node_t ** root)
{
  rb_node_t *parent, *gparent;

  node->rb_color = RB_RED;
  while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
    {
      gparent = parent->rb_parent;

      if (parent == gparent->rb_left)
	{
	  {
	    register rb_node_t *uncle = gparent->rb_right;
	    if (uncle && uncle->rb_color == RB_RED)
	      {
		uncle->rb_color = RB_BLACK;
		parent->rb_color = RB_BLACK;
		gparent->rb_color = RB_RED;
		node = gparent;
		continue;
	      }
	  }

	  if (parent->rb_right == node)
	    {
	      register rb_node_t *tmp;
	      rb_rotate_left (parent, root);
	      tmp = parent;
	      parent = node;
	      node = tmp;
	    }

	  parent->rb_color = RB_BLACK;
	  gparent->rb_color = RB_RED;
	  rb_rotate_right (gparent, root);
	}
      else
	{
	  {
	    register rb_node_t *uncle = gparent->rb_left;
	    if (uncle && uncle->rb_color == RB_RED)
	      {
		uncle->rb_color = RB_BLACK;
		parent->rb_color = RB_BLACK;
		gparent->rb_color = RB_RED;
		node = gparent;
		continue;
	      }
	  }

	  if (parent->rb_left == node)
	    {
	      register rb_node_t *tmp;
	      rb_rotate_right (parent, root);
	      tmp = parent;
	      parent = node;
	      node = tmp;
	    }

	  parent->rb_color = RB_BLACK;
	  gparent->rb_color = RB_RED;
	  rb_rotate_left (gparent, root);
	}
    }

  (*root)->rb_color = RB_BLACK;
}
Beispiel #4
0
/** 在树中的结点被删除后调整平衡 */
static rb_node_t*
rb_erase_rebalance( rb_node_t *node, rb_node_t *parent, rb_node_t *root )
{
	rb_node_t *other, *o_left, *o_right;
   
	while ((!node || node->color == BLACK) && node != root) {  
		if (parent->left == node) {  
			other = parent->right;
			if (other->color == RED) {  
				other->color = BLACK;	
				parent->color = RED;
				root = rb_rotate_left(parent, root);
				other = parent->right;
			}
			if ((!other->left || other->left->color == BLACK) 
			 && (!other->right || other->right->color == BLACK)) {
				other->color = RED;
				node = parent;
				parent = node->parent;
			} else {
				if (!other->right || other->right->color == BLACK) {  
					if ((o_left = other->left)) {
						o_left->color = BLACK;
					}   
					other->color = RED;
					root = rb_rotate_right(other, root);
					other = parent->right;
				}
				other->color = parent->color;
				parent->color = BLACK;
				if (other->right) {
					other->right->color = BLACK;
				}  
				root = rb_rotate_left(parent, root);
				node = root;
				break;  
			}  
		} else {
			other = parent->left;  
			if (other->color == RED) {  
				other->color = BLACK;  
				parent->color = RED;  
				root = rb_rotate_right(parent, root);  
				other = parent->left;  
			}  
			if ((!other->left || other->left->color == BLACK) &&  
				(!other->right || other->right->color == BLACK)) {  
				other->color = RED;  
				node = parent;  
				parent = node->parent;  
			} else {  
				if (!other->left || other->left->color == BLACK) {  
					if ((o_right = other->right)) {  
						o_right->color = BLACK;  
					}  
					other->color = RED;  
					root = rb_rotate_left(other, root);  
					other = parent->left;  
				}  
				other->color = parent->color;  
				parent->color = BLACK;  
				if (other->left) {
					other->left->color = BLACK;  
				}  
				root = rb_rotate_right(parent, root);  
				node = root;  
				break;  
			}  
		}  
	}  
   
	if( node ) {
		node->color = BLACK;
	}
	return root;
}
Beispiel #5
0
rb_node_t* rb_delete_fixup(rb_node_t* root,rb_node_t* nodex)
{
	rb_node_t* nodew;
	while(nodex == root && nodex->color == BLACK)
	{
		if(nodex == nodex->parent->lchild)
		{
		  nodew = nodex->parent->rchild;
		  if(nodew->color == RED)
		  {
			  nodew->color = BLACK;
			  nodex->parent->color = RED;
			  root = rb_rotate_left(root,nodex->parent);
			  nodew = nodex->parent.rchild;
		  }
		  if(nodew->lchild->color == BLACK && nodew->rchild->color == BLACK)
		  {
			  nodew->color = RED;
			  nodex = nodex->parent;
		  }
		  else
		  {
			  if(nodew->rchild->color == BLACK)
			  {
				  nodew->lchild->color = BLACK;
				  nodew->color = RED;
				  root = rb_rotate_right(root,nodew);
				  nodew = nodex->parent->rchild;
			  }
			  nodew->color = nodex->parent->color;
			  nodex->parent->color = BLACK;
			  nodew->rchild->color = BLACK;
			  root = rb_rotate_left(root,nodex->parent);
			  nodex = root;
		  }
		}
		else
		{

			  nodew = nodex->parent->lchild;
			  if(nodew->color == RED)
			  {
				  nodew->color = BLACK;
				  nodex->parent->color = RED;
				  root = rb_rotate_right(root,nodex->parent);
				  nodew = nodex->parent.lchild;
			  }
			  if(nodew->lchild->color == BLACK && nodew->rchild->color == BLACK)
			  {
				  nodew->color = RED;
				  nodex = nodex->parent;
			  }
			  else
			  {
				  if(nodew->lchild->color == BLACK)
				  {
					  nodew->rchild->color = BLACK;
					  nodew->color = RED;
					  root = rb_rotate_left(root,nodew);
					  nodew = nodex->parent->lchild;
				  }
				  nodew->color = nodex->parent->color;
				  nodex->parent->color = BLACK;
				  nodew->lchild->color = BLACK;
				  root = rb_rotate_right(root,nodex->parent);
				  nodex = root;
			  }

		}
	}
	nodex->color = BLACK;
	return root;
}
Beispiel #6
0
static void
rb_erase_rebalance (rb_node_t * child, rb_node_t * parent, rb_node_t ** root)
{
  rb_node_t *other;

  while ((!child || child->rb_color == RB_BLACK) && child != *root)
    {
      if (parent->rb_left == child)
	{
	  other = parent->rb_right;
	  if (other->rb_color == RB_RED)
	    {
	      other->rb_color = RB_BLACK;
	      parent->rb_color = RB_RED;
	      rb_rotate_left (parent, root);
	      other = parent->rb_right;
	    }
	  if ((!other->rb_left ||
	       other->rb_left->rb_color == RB_BLACK)
	      && (!other->rb_right || other->rb_right->rb_color == RB_BLACK))
	    {
	      other->rb_color = RB_RED;
	      child = parent;
	      parent = child->rb_parent;
	    }
	  else
	    {
	      if (!other->rb_right || other->rb_right->rb_color == RB_BLACK)
		{
		  register rb_node_t *o_left;
		  if ((o_left = other->rb_left))
		    o_left->rb_color = RB_BLACK;
		  other->rb_color = RB_RED;
		  rb_rotate_right (other, root);
		  other = parent->rb_right;
		}
	      other->rb_color = parent->rb_color;
	      parent->rb_color = RB_BLACK;
	      if (other->rb_right)
		other->rb_right->rb_color = RB_BLACK;
	      rb_rotate_left (parent, root);
	      child = *root;
	      break;
	    }
	}
      else
	{
	  other = parent->rb_left;
	  if (other->rb_color == RB_RED)
	    {
	      other->rb_color = RB_BLACK;
	      parent->rb_color = RB_RED;
	      rb_rotate_right (parent, root);
	      other = parent->rb_left;
	    }
	  if ((!other->rb_left ||
	       other->rb_left->rb_color == RB_BLACK)
	      && (!other->rb_right || other->rb_right->rb_color == RB_BLACK))
	    {
	      other->rb_color = RB_RED;
	      child = parent;
	      parent = child->rb_parent;
	    }
	  else
	    {
	      if (!other->rb_left || other->rb_left->rb_color == RB_BLACK)
		{
		  register rb_node_t *o_right;
		  if ((o_right = other->rb_right))
		    o_right->rb_color = RB_BLACK;
		  other->rb_color = RB_RED;
		  rb_rotate_left (other, root);
		  other = parent->rb_left;
		}
	      other->rb_color = parent->rb_color;
	      parent->rb_color = RB_BLACK;
	      if (other->rb_left)
		other->rb_left->rb_color = RB_BLACK;
	      rb_rotate_right (parent, root);
	      child = *root;
	      break;
	    }
	}
    }
  if (child)
    child->rb_color = RB_BLACK;
}
Beispiel #7
0
/** 在树中的结点被删除后调整平衡 */
static RBTreeNode*
rb_erase_rebalance( RBTreeNode *node, RBTreeNode *parent,
		    RBTreeNode *root )
{
	RBTreeNode *other, *o_left, *o_right;

	while( (!node || node->color == BLACK) && node != root ) {
		if( parent->left == node ) {
			other = parent->right;
			if( other->color == RED ) {
				other->color = BLACK;
				parent->color = RED;
				root = rb_rotate_left( parent, root );
				other = parent->right;
			}
			if( (!other->left || other->left->color == BLACK)
			    && (!other->right || other->right->color == BLACK) ) {
				other->color = RED;
				node = parent;
				parent = node->parent;
				continue;
			}
			if( !other->right || other->right->color == BLACK ) {
				if( (o_left = other->left) ) {
					o_left->color = BLACK;
				}
				other->color = RED;
				root = rb_rotate_right( other, root );
				other = parent->right;
			}
			other->color = parent->color;
			parent->color = BLACK;
			if( other->right ) {
				other->right->color = BLACK;
			}
			root = rb_rotate_left( parent, root );
			node = root;
			break;
		}

		other = parent->left;
		if( other->color == RED ) {
			other->color = BLACK;
			parent->color = RED;
			root = rb_rotate_right( parent, root );
			other = parent->left;
		}
		if( (!other->left || other->left->color == BLACK)
		    && (!other->right || other->right->color == BLACK) ) {
			other->color = RED;
			node = parent;
			parent = node->parent;
			continue;
		}

		if( !other->left || other->left->color == BLACK ) {
			if( (o_right = other->right) ) {
				o_right->color = BLACK;
			}
			other->color = RED;
			root = rb_rotate_left( other, root );
			other = parent->left;
		}
		other->color = parent->color;
		parent->color = BLACK;
		if( other->left ) {
			other->left->color = BLACK;
		}
		root = rb_rotate_right( parent, root );
		node = root;
		break;
	}

	if( node ) {
		node->color = BLACK;
	}
	return root;
}
Beispiel #8
0
//七、红黑树的4种删除情况  
//----------------------------------------------------------------  
//红黑树修复删除的4种情况  
//为了表示下述注释的方便,也为了让下述代码与我的倆篇文章相对应,  
//x表示要删除的结点,*other、w表示兄弟结点,  
//----------------------------------------------------------------  
rb_node_t* rb_erase_fixup(rb_node_t *node, rb_node_t *parent, rb_node_t *root)  
{  
    rb_node_t *other, *o_left, *o_right;   //x的兄弟*other,兄弟左孩子*o_left,*o_right  
   
    while ((!node || node->color == BLACK) && node != root)   
    {  
        if (parent->left == node)  
        {  
            other = parent->right;  
            if (other->color == RED)   //情况1:x的兄弟w是红色的  
            {  
                other->color = BLACK;    
                parent->color = RED;   //上俩行,改变颜色,w->黑、p[x]->红。  
                root = rb_rotate_left(parent, root);  //再对p[x]做一次左旋  
                other = parent->right;  //x的新兄弟new w 是旋转之前w的某个孩子。其实就是左旋后的效果。  
            }  
            if ((!other->left || other->left->color == BLACK) &&  
                (!other->right || other->right->color == BLACK))    
                          //情况2:x的兄弟w是黑色,且w的俩个孩子也都是黑色的  
  
            {                         //由于w和w的俩个孩子都是黑色的,则在x和w上得去掉一黑色,  
                other->color = RED;   //于是,兄弟w变为红色。  
                node = parent;    //p[x]为新结点x  
                parent = node->parent;  //x<-p[x]  
            }  
            else                       //情况3:x的兄弟w是黑色的,  
            {                          //且,w的左孩子是红色,右孩子为黑色。  
                if (!other->right || other->right->color == BLACK)  
                {  
                    if ((o_left = other->left))   //w和其左孩子left[w],颜色交换。  
                    {  
                        o_left->color = BLACK;    //w的左孩子变为由黑->红色  
                    }   
                    other->color = RED;           //w由黑->红  
                    root = rb_rotate_right(other, root);  //再对w进行右旋,从而红黑性质恢复。  
                    other = parent->right;        //变化后的,父结点的右孩子,作为新的兄弟结点w。  
                }  
                            //情况4:x的兄弟w是黑色的  
      
                other->color = parent->color;  //把兄弟节点染成当前节点父节点的颜色。  
                parent->color = BLACK;  //把当前节点父节点染成黑色  
                if (other->right)      //且w的右孩子是红  
                {  
                    other->right->color = BLACK;  //兄弟节点w右孩子染成黑色  
                }  
                root = rb_rotate_left(parent, root);  //并再做一次左旋  
                node = root;   //并把x置为根。  
                break;  
            }  
        }  
        //下述情况与上述情况,原理一致。分析略。  
        else  
        {  
            other = parent->left;  
            if (other->color == RED)  
            {  
                other->color = BLACK;  
                parent->color = RED;  
                root = rb_rotate_right(parent, root);  
                other = parent->left;  
            }  
            if ((!other->left || other->left->color == BLACK) &&  
                (!other->right || other->right->color == BLACK))  
            {  
                other->color = RED;  
                node = parent;  
                parent = node->parent;  
            }  
            else  
            {  
                if (!other->left || other->left->color == BLACK)  
                {  
                    if ((o_right = other->right))  
                    {  
                        o_right->color = BLACK;  
                    }  
                    other->color = RED;  
                    root = rb_rotate_left(other, root);  
                    other = parent->left;  
                }  
                other->color = parent->color;  
                parent->color = BLACK;  
                if (other->left)  
                {  
                    other->left->color = BLACK;  
                }  
                root = rb_rotate_right(parent, root);  
                node = root;  
                break;  
            }  
        }  
    }  
   
    if (node)  
    {  
        node->color = BLACK;  //最后将node[上述步骤置为了根结点],改为黑色。  
    }    
    return root;  //返回root  
}  
Beispiel #9
0
//五、红黑树的3种插入情况  
//接下来,咱们重点分析针对红黑树插入的3种情况,而进行的修复工作。  
//--------------------------------------------------------------  
//红黑树修复插入的3种情况  
//为了在下面的注释中表示方便,也为了让下述代码与我的倆篇文章相对应,  
//用z表示当前结点,p[z]表示父母、p[p[z]]表示祖父、y表示叔叔。  
//--------------------------------------------------------------  
rb_node_t* rb_insert_fixup(rb_node_t *node, rb_node_t *root)  
{  
    rb_node_t *parent, *gparent, *uncle, *tmp;  //父母p[z]、祖父p[p[z]]、叔叔y、临时结点*tmp  
   
    while ((parent = node->parent) && parent->color == RED)  
    {     //parent 为node的父母,且当父母的颜色为红时  
        gparent = parent->parent;   //gparent为祖父  
    
        if (parent == gparent->left)  //当祖父的左孩子即为父母时。  
                                 //其实上述几行语句,无非就是理顺孩子、父母、祖父的关系。:D。  
        {  
            uncle = gparent->right;  //定义叔叔的概念,叔叔y就是父母的右孩子。  
  
            if (uncle && uncle->color == RED) //情况1:z的叔叔y是红色的  
            {  
                uncle->color = BLACK;   //将叔叔结点y着为黑色  
                parent->color = BLACK;  //z的父母p[z]也着为黑色。解决z,p[z]都是红色的问题。  
                gparent->color = RED;    
                node = gparent;     //将祖父当做新增结点z,指针z上移俩层,且着为红色。  
            //上述情况1中,只考虑了z作为父母的右孩子的情况。  
            }  
            else                     //情况2:z的叔叔y是黑色的,  
            {     
                if (parent->right == node)  //且z为右孩子  
                {  
                    root = rb_rotate_left(parent, root); //左旋[结点z,与父母结点]  
                    tmp = parent;  
                    parent = node;  
                    node = tmp;     //parent与node 互换角色  
                }  
                             //情况3:z的叔叔y是黑色的,此时z成为了左孩子。  
                                    //注意,1:情况3是由上述情况2变化而来的。  
                                    //......2:z的叔叔总是黑色的,否则就是情况1了。  
                parent->color = BLACK;   //z的父母p[z]着为黑色  
                gparent->color = RED;    //原祖父结点着为红色  
                root = rb_rotate_right(gparent, root); //右旋[结点z,与祖父结点]  
            }  
        }   
   
        else   
        {       
        // if (parent == gparent->right) 当祖父的右孩子即为父母时。(解释请看本文评论下第23楼,同时,感谢SupremeHover指正!)  
            uncle = gparent->left;  //祖父的左孩子作为叔叔结点。[原理还是与上部分一样的]  
            if (uncle && uncle->color == RED)  //情况1:z的叔叔y是红色的  
            {  
                uncle->color = BLACK;  
                parent->color = BLACK;  
                gparent->color = RED;  
                node = gparent;           //同上。  
            }  
            else                               //情况2:z的叔叔y是黑色的,  
            {  
                if (parent->left == node)  //且z为左孩子  
                {  
                    root = rb_rotate_right(parent, root);  //以结点parent、root右旋  
                    tmp = parent;  
                    parent = node;  
                    node = tmp;       //parent与node 互换角色  
                }   
                  //经过情况2的变化,成为了情况3.  
                parent->color = BLACK;  
                gparent->color = RED;  
                root = rb_rotate_left(gparent, root);   //以结点gparent和root左旋  
            }  
        }  
    }  
   
    root->color = BLACK; //根结点,不论怎样,都得置为黑色。  
    return root;      //返回根结点。  
}  
Beispiel #10
0
void rb_insert_color(struct rb_node* node, struct rb_root* root)
{
  int _switch = 1;
  struct rb_node *g_node, *u_node;

  while (_switch)
  {
    /* Sets Helper Nodes
     * g_node is so-called "grandparent" node of node
     * u_node is so-called "uncle" node of node
     * */
    g_node = ((node != NULL) && (node->rb_parent != NULL)) ? \
             node->rb_parent->rb_parent \
             : NULL;
    u_node = (g_node != NULL) ? \
             ((node->rb_parent == g_node->rb_left) ? g_node->rb_right : g_node->rb_left) \
             : NULL;

    switch (_switch)
    {
      case 1:
        if (node->rb_parent == NULL)
        {
          node->color = BLACK;
          _switch = 0;
          break;
        }
      case 2:
        if (node->rb_parent->color == BLACK)
        {
          node->color = RED;
          _switch = 0;
          break;
        }
      case 3:
        if ((u_node != NULL) && (u_node->color != RED))
        {
          node->rb_parent->color = BLACK;
          u_node->color = BLACK;
          g_node->color = RED;
          _switch = 1;
          node = g_node;
          break;
        }
      case 4:
        if ((node == node->rb_parent->rb_right) && (node->rb_parent == g_node->rb_left))
        {
          rb_rotate_left(root, node->rb_parent);
          node = node->rb_left;
        }
        else if ((node == node->rb_parent->rb_left) && (node->rb_parent = g_node->rb_right))
        {
          rb_rotate_right(root, node->rb_parent);
          node = node->rb_right;
        }
        _switch = 5;
        break;
      case 5:
        node->rb_parent->color = BLACK;
        g_node->color = RED;
        if (node == node->rb_parent->rb_left)
          rb_rotate_right(root, g_node);
        else
          rb_rotate_left(root, g_node);
      default:
        _switch = 0;
        break;
    }
  }
}
Beispiel #11
0
void rb_erase(struct rb_node *node, struct rb_root* root)
{
  struct rb_node *t_node, *tp_node;
  struct rb_node *s_node, *c_node;
  int _switch = 1;

  if ((node->rb_left != NULL)&&(node->rb_right != NULL))
  {
    for (t_node = node; t_node->rb_right != NULL; t_node = t_node->rb_right);

    tp_node = t_node->rb_parent;

    rb_replace_node (root, node, t_node);

    tp_node->rb_right = node;
    node->rb_parent = tp_node;

    tp_node = t_node->rb_left;

    t_node->rb_left = node->rb_left;
    t_node->rb_right = node->rb_right;

    node->rb_left = tp_node;
    node->rb_right = NULL;
  }

  c_node = (node->rb_right == NULL) ? node->rb_left: node->rb_right;
  t_node = node;

  if (node->color == BLACK)
  {
    node->color = c_node->color;

    while (_switch)
    {
      s_node = (node->rb_parent != NULL) ? \
               ((node->rb_parent->rb_left == node) ? node->rb_parent->rb_right : node->rb_parent->rb_left) \
               : NULL;
      switch(_switch)
      {
        case 1:
          if (node->rb_parent == NULL)
          {
            _switch = 0;
            break;
          }
        case 2:
          if (s_node->color == RED)
          {
            node->rb_parent->color = RED;
            s_node->color = BLACK;
            if (node == node->rb_parent->rb_left)
              rb_rotate_left(root, node->rb_parent);
            else
              rb_rotate_right(root, node->rb_parent);
            _switch = 0;
            break;
          }
        case 3:
          if ((node->rb_parent->color == BLACK) && \
              (s_node->color == BLACK) && \
              (s_node->rb_left->color == BLACK) && \
              (s_node->rb_right->color == BLACK))
          {
            s_node->color = RED;
            _switch = 1;
            node = node->rb_parent;
            break;
          }
        case 4:
          if ((node->rb_parent->color == RED) && \
              (s_node->color == BLACK) && \
              (s_node->rb_left->color == BLACK) && \
              (s_node->rb_right->color == BLACK))
          {
            s_node->color = RED;
            node->rb_parent->color = BLACK;
            _switch = 0;
            break;
          }
        case 5:
          if (s_node->color == BLACK)
          {
            if ((node == node->rb_parent->rb_left) && \
                (s_node->rb_right->color == BLACK) && \
                (s_node->rb_left->color == RED))
            {
              s_node->color = RED;
              s_node->rb_left->color = BLACK;
              rb_rotate_right(root, s_node);
            }
            else if((node == node->rb_parent->rb_right) && \
                (s_node->rb_left->color == BLACK) && \
                (s_node->rb_right->color = RED))
            {
              s_node->color = RED;
              s_node->rb_right->color = BLACK;
              rb_rotate_left(root, s_node);
            }
            _switch = 0;
            break;
          }
        case 6:
          s_node->color = node->rb_parent->color;
          node->rb_parent->color = BLACK;

          if (node == node->rb_parent->rb_left)
          {
            s_node->rb_right->color = BLACK;
            rb_rotate_left(root, node->rb_parent);
          }
          else
          {
            s_node->rb_left->color = BLACK;
            rb_rotate_right(root, node->rb_parent);
          }
          _switch = 0;
          break;
        default:
          _switch = 0;
          break;
      }
    }
  }
  rb_replace_node (root, t_node, c_node);
}