Пример #1
0
/*
 * rb_fix - restore properties of Red-black tree after deleting
 */
static void rb_fix(void *node){
    void *root, *sib;
    root = RB_LEFT(rb_root);
    while(!RB_RED(node) && node != root){
        if(node == RB_LEFT(RB_PARENT(node))){
            sib = RB_RIGHT(RB_PARENT(node));
            if(RB_RED(sib)){
                RB_RED(sib) = 0;
                RB_RED(RB_PARENT(node)) = 1;
                rb_rotate_left(RB_PARENT(node));
                sib = RB_RIGHT(RB_PARENT(node));
            }
            if(!RB_RED(RB_RIGHT(sib)) && !RB_RED(RB_LEFT(sib))){
                RB_RED(sib) = 1;
                node = RB_PARENT(node);
            }else{
                if(!RB_RED(RB_RIGHT(sib))){
                    RB_RED(RB_LEFT(sib)) = 0;
                    RB_RED(sib) = 1;
                    rb_rotate_right(sib);
                    sib = RB_RIGHT(RB_PARENT(node));
                }
                RB_RED(sib) = RB_RED(RB_PARENT(node));
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(RB_RIGHT(sib)) = 0;
                rb_rotate_left(RB_PARENT(node));
                node = root;
            }
        }else{
            sib = RB_LEFT(RB_PARENT(node));
            if(RB_RED(sib)){
                RB_RED(sib) = 0;
                RB_RED(RB_PARENT(node)) = 1;
                rb_rotate_right(RB_PARENT(node));
                sib = RB_LEFT(RB_PARENT(node));
            }
            if(!RB_RED(RB_RIGHT(sib)) && !RB_RED(RB_LEFT(sib))){
                RB_RED(sib) = 1;
                node = RB_PARENT(node);
            }else{
                if(!RB_RED(RB_LEFT(sib))){
                    RB_RED(RB_RIGHT(sib)) = 0;
                    RB_RED(sib) = 1;
                    rb_rotate_left(sib);
                    sib = RB_LEFT(RB_PARENT(node));
                }
                RB_RED(sib) = RB_RED(RB_PARENT(node));
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(RB_LEFT(sib)) = 0;
                rb_rotate_right(RB_PARENT(node));
                node = root;
            }
        }
        
    }
    RB_RED(node) = 0;
}
Пример #2
0
rb_node_t* rb_insert_fixup(rb_node_t* root, rb_node_t* nodez)
{
	rb_node_t* nodey;
	while(nodez->parent->color == RED)
	{
		if(nodez->parent == nodez->parent->parent->lchild)
		{
			nodey = nodez->parent->parent->rchild;
			if(nodey->color == RED)
			{
				nodez->parent->color = BLACK;
				nodey->color = BLACK;
                nodey->parent->color = RED;
                nodez = nodez->parent->parent;
			}
			else
			{
				if(nodez == nodez->parent->rchild)
				{
					nodez = nodez->parent;
					root = rb_rotate_left(root,nodez);
				}
				nodez->parent->color = BLACK;
				nodez->parent->parent->color = RED;
				root = rb_rotate_right(root,nodez->parent->parent);
			}
		}
		else
		{
			nodey = nodez->parent->parent->lchild;
			if(nodey->color == RED)
			{
				nodez->parent->color = BLACK;
				nodey->color = BLACK;
			    nodey->parent->color = RED;
			    nodez = nodez->parent->parent;
			}
			else
			{
				if(nodez == nodez->parent->lchild)
				{
					nodez = nodez->parent;
					root = rb_rotate_right(root,nodez);
				}
				nodez->parent->color = BLACK;
				nodez->parent->parent->color = RED;
				root = rb_rotate_left(root,nodez->parent->parent);
			}
		}

	}

	root->color = BLACK;
	return root;
}
Пример #3
0
static rb_node_t*
rb_insert_rebalance( rb_node_t *root, rb_node_t *node )
{
	rb_node_t *parent, *gparent, *uncle, *tmp;
   
	while ((parent = node->parent) && parent->color == RED) {
		gparent = parent->parent;
	
		if (parent == gparent->left) {  
			uncle = gparent->right;
			if (uncle && uncle->color == RED) {  
				uncle->color = BLACK;
				parent->color = BLACK;
				gparent->color = RED;	
				node = gparent;
			} else {
				if (parent->right == node) {
					root = rb_rotate_left(parent, root);
					tmp = parent;
					parent = node;
					node = tmp;
				}
				parent->color = BLACK;
				gparent->color = RED;
				root = rb_rotate_right(gparent, root);
			}  
		} else {
			uncle = gparent->left;
			if (uncle && uncle->color == RED) {
				uncle->color = BLACK;  
				parent->color = BLACK;  
				gparent->color = RED;  
				node = gparent;
			} else {
				if (parent->left == node) {
					root = rb_rotate_right(parent, root);
					tmp = parent;
					parent = node;
					node = tmp;
				}
				parent->color = BLACK;  
				gparent->color = RED;  
				root = rb_rotate_left(gparent, root);
			}  
		}
	}  
   
	root->color = BLACK;
	return root;
}
Пример #4
0
void rb_insert_case5(struct rb_tree_node *n)
{
  struct rb_tree_node * p = n->parent;
  struct rb_tree_node * g = p->parent;
  p->color = BLACK;
  g->color = RED;
  if (n == p->left)
    rb_rotate_right(g);
  else
    rb_rotate_left(g);
}
Пример #5
0
/* In this final case, we deal with two cases that are mirror images of one
   another:
   * The new node is the left child of its parent and the parent is the left
   child of the grandparent. In this case we rotate right about the
   grandparent.
   * The new node is the right child of its parent and the parent is the right
   child of the grandparent. In this case we rotate left about the
   grandparent.
   Now the properties are satisfied and all cases have been covered. */
static void rb_link_5(struct rb_tree *t, struct rb_node *n,
                      struct rb_callbacks *cb) {
  n->parent->color = RB_BLACK;
  rb_grandparent(n)->color = RB_RED;
  if (n == n->parent->left && n->parent == rb_grandparent(n)->left) {
    rb_rotate_right(t, rb_grandparent(n), cb);
  } else {
    CHECK(n == n->parent->right && n->parent == rb_grandparent(n)->right);
    rb_rotate_left(t, rb_grandparent(n), cb);
  }
}
Пример #6
0
/* In this case, we deal with two cases that are mirror images of one another:
   * The new node is the right child of its parent and the parent is the left
   child of the grandparent. In this case we rotate left about the parent.
   * The new node is the left child of its parent and the parent is the right
   child of the grandparent. In this case we rotate right about the parent.
   Neither of these fixes the properties, but they put the tree in the correct
   form to apply case 5. */
static void rb_link_4(struct rb_tree *t, struct rb_node *n,
                      struct rb_callbacks *cb) {
  if (n == n->parent->right && n->parent == rb_grandparent(n)->left) {
    rb_rotate_left(t, n->parent, cb);
    n = n->left;
  } else if (n == n->parent->left && n->parent == rb_grandparent(n)->right) {
    rb_rotate_right(t, n->parent, cb);
    n = n->right;
  }

  rb_link_5(t, n, cb);
}
Пример #7
0
void rb_insert_case4(struct rb_tree_node *n)
{
  struct rb_tree_node * p = n->parent;
  struct rb_tree_node * g = p->parent;
  if ((n == p->right) && (p == g->left)) {
    rb_rotate_left(p);
    n = n->left;
  } else if ((n == p->left) && (p == g->right)) {
    rb_rotate_right(p);
    n = n->right;
  }
  rb_insert_case5(n);
}
Пример #8
0
/* N has a red sibling. In this case we exchange the colors of the parent and
   sibling, then rotate about the parent so that the sibling becomes the
   parent of its former parent. This does not restore the tree properties, but
   reduces the problem to one of the remaining cases. */
static void rb_unlink_2(struct rb_tree *t, struct rb_node *n,
                        struct rb_callbacks *cb) {
  if (rb_color(rb_sibling(n)) == RB_RED) {
    n->parent->color = RB_RED;
    rb_sibling(n)->color = RB_BLACK;
    if (n == n->parent->left) {
      rb_rotate_left(t, n->parent, cb);
    } else {
      rb_rotate_right(t, n->parent, cb);
    }
  }

  rb_unlink_3(t, n, cb);
}
Пример #9
0
/* There are two cases handled here which are mirror images of one another:
   * N's sibling S is black, S's right child is red, and N is the left child
   of its parent. We exchange the colors of N's parent and sibling, make S's
   right child black, then rotate left at N's parent.
   * N's sibling S is black, S's left child is red, and N is the right child
   of its parent. We exchange the colors of N's parent and sibling, make S's
   left child black, then rotate right at N's parent.

   This accomplishes three things at once:
   * We add a black node to all paths through N, either by adding a black S to
   those paths or by recoloring N's parent black.
   * We remove a black node from all paths through S's red child, either by
   removing P from those paths or by recoloring S.
   * We recolor S's red child black, adding a black node back to all paths
   through S's red child.

   S's left child has become a child of N's parent during the rotation and so
   is unaffected. */
static void rb_unlink_6(struct rb_tree *t, struct rb_node *n,
                        struct rb_callbacks *cb) {
  rb_sibling(n)->color = rb_color(n->parent);
  n->parent->color = RB_BLACK;
  if (n == n->parent->left) {
    CHECK_EQ(rb_color(rb_sibling(n)->right), RB_RED);
    rb_sibling(n)->right->color = RB_BLACK;
    rb_rotate_left(t, n->parent, cb);
  } else {
    CHECK_EQ(rb_color(rb_sibling(n)->left), RB_RED);
    rb_sibling(n)->left->color = RB_BLACK;
    rb_rotate_right(t, n->parent, cb);
  }
}
Пример #10
0
/* There are two cases handled here which are mirror images of one another:
   * N's sibling S is black, S's left child is red, S's right child is black,
   and N is the left child of its parent. We exchange the colors of S and its
   left sibling and rotate right at S.
   * N's sibling S is black, S's right child is red, S's left child is black,
   and N is the right child of its parent. We exchange the colors of S and its
   right sibling and rotate left at S.
   Both of these function to reduce us to the situation described in case 6. */
static void rb_unlink_5(struct rb_tree *t, struct rb_node *n,
                        struct rb_callbacks *cb) {
  if (n == n->parent->left && rb_color(rb_sibling(n)) == RB_BLACK &&
      rb_color(rb_sibling(n)->left) == RB_RED &&
      rb_color(rb_sibling(n)->right) == RB_BLACK) {
    rb_sibling(n)->color = RB_RED;
    rb_sibling(n)->left->color = RB_BLACK;
    rb_rotate_right(t, rb_sibling(n), cb);
  } else if (n == n->parent->right && rb_color(rb_sibling(n)) == RB_BLACK &&
             rb_color(rb_sibling(n)->right) == RB_RED &&
             rb_color(rb_sibling(n)->left) == RB_BLACK) {
    rb_sibling(n)->color = RB_RED;
    rb_sibling(n)->right->color = RB_BLACK;
    rb_rotate_left(t, rb_sibling(n), cb);
  }

  rb_unlink_6(t, n, cb);
}
Пример #11
0
void rb_insert_rebalance(struct rb_node* node, struct rb_root* root)
{
    struct rb_node *parent, *gparent, *uncle;

    while ((parent = rb_parent(node)) && rb_is_red(parent)) {

        gparent = rb_parent(parent);

        if (parent == gparent->left) {
            uncle = gparent->right;
            if (uncle && rb_is_red(uncle)) {
                rb_set_black(uncle);
                rb_set_black(parent);
                rb_set_red(gparent);
                node = gparent;

                continue;
            }

            if (node == parent->right) {
                register struct rb_node* tmp;

                rb_rotate_left(parent, root);
                tmp = node;
                node = parent;
                parent = tmp;
            }

            rb_rotate_right(gparent, root);
            rb_set_black(parent);
            rb_set_red(gparent);

            continue;
        }

        uncle = gparent->left;
        if (uncle && rb_is_red(uncle)) {
            rb_set_black(parent);
            rb_set_black(uncle);
            rb_set_red(gparent);
            node = gparent;

            continue;
        }

        if (node == parent->left) {
            register struct rb_node* tmp;

            rb_rotate_right(parent, root);
            tmp = node;
            node = parent;
            parent = tmp;
        }

        rb_rotate_left(gparent, root);
        rb_set_red(gparent);
        rb_set_black(parent);
    }

    rb_set_black(root->node);
}
Пример #12
0
static inline void rb_delete_rebalance(struct rb_node* node,
                                       struct rb_node* parent,
                                       struct rb_root* root)
{
    struct rb_node* sibling;

    while ((!node || rb_is_black(node)) && (node != root->node)) {
        if (node == parent->left) {
            sibling = parent->right;

            if (rb_is_red(sibling)) {
                rb_rotate_left(parent, root);
                rb_set_red(parent);
                rb_set_black(sibling);
                sibling = parent->right;
            }

            if ((!sibling->left || rb_is_black(sibling->left)) &&
                (!sibling->right || rb_is_black(sibling->right))) {
                rb_set_red(sibling);
                node = parent;
                /* if (node) */ parent = rb_parent(node);
            } else {
                if (!sibling->right || rb_is_black(sibling->right)) {
                    rb_set_black(sibling->left);
                    rb_set_red(sibling);
                    rb_rotate_right(sibling, root);
                    sibling = parent->right;
                }

                rb_set_color(sibling, rb_color(parent));
                rb_set_black(parent);
                rb_set_black(sibling->right);
                rb_rotate_left(parent, root);
                node = root->node;

                break;
            }
        } else {
            sibling = parent->left;

            if (rb_is_red(sibling)) {
                rb_rotate_right(parent, root);
                rb_set_red(parent);
                rb_set_black(sibling);
                sibling = parent->left;
            }

            if ((!sibling->left || rb_is_black(sibling->left)) &&
                (!sibling->right || rb_is_black(sibling->right))) {
                rb_set_red(sibling);
                node = parent;
                /* if (node) */ parent = rb_parent(node);
            } else {
                if (!sibling->left || rb_is_black(sibling->left)) {
                    rb_set_black(sibling->right);
                    rb_set_red(sibling);
                    rb_rotate_left(sibling, root);
                    sibling = parent->left;
                }

                rb_set_color(sibling, rb_color(parent));
                rb_set_black(parent);
                rb_set_black(sibling->left);
                rb_rotate_right(parent, root);
                node = root->node;

                break;
            }
        }
    }

    if (node)
        rb_set_black(node);
}
Пример #13
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;
}
Пример #14
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;
}
Пример #15
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;
}
Пример #16
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;
}
Пример #17
0
static char *rbtree_insert(char *node, char **tree)
{
    char *key, *parent;
    int is_left;

    key = rb_do_lookup(node, *tree, &parent, &is_left);
    if (key)
        return key;

    rb_set_left(NULL, node);
    rb_set_right(NULL, node);
    rb_set_color(RB_RED, node);
    rb_set_parent(parent, node);

    if (parent) {
        rb_set_child(node, parent, is_left);
    } else {
        *tree = node;
    }

    /*
     * Fixup the modified tree by recoloring nodes and performing
     * rotations (2 at most) hence the red-black tree properties are
     * preserved.
     */
    while ((parent = rb_get_parent(node)) && rb_is_red(parent)) {
        char *grandpa = rb_get_parent(parent);

        if (parent == rbtree_get_left(grandpa)) {
            char *uncle = rbtree_get_right(grandpa);

            if (uncle && rb_is_red(uncle)) {
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_BLACK, uncle);
                rb_set_color(RB_RED, grandpa);
                node = grandpa;
            } else {
                if (node == rbtree_get_right(parent)) {
                    rb_rotate_left(parent, tree);
                    node = parent;
                    parent = rb_get_parent(node);
                }
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_RED, grandpa);
                rb_rotate_right(grandpa, tree);
            }
        } else {
            char *uncle = rbtree_get_left(grandpa);

            if (uncle && rb_is_red(uncle)) {
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_BLACK, uncle);
                rb_set_color(RB_RED, grandpa);
                node = grandpa;
            } else {
                if (node == rbtree_get_left(parent)) {
                    rb_rotate_right(parent, tree);
                    node = parent;
                    parent = rb_get_parent(node);
                }
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_RED, grandpa);
                rb_rotate_left(grandpa, tree);
            }
        }
    }
    rb_set_color(RB_BLACK, *tree);
    return NULL;
}
Пример #18
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;      //返回根结点。  
}  
Пример #19
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  
}  
Пример #20
0
/*
	用z表示当前节点,p[z]表示父节点,p[p[z]]表示祖父节点,y表示叔叔
*/
static rb_node_t *rb_insert_rebalance(rb_node_t *node, rb_node_t *root)
{
	rb_node_t *parent;//父节点p[z]
	rb_node_t *gparent;//祖父节点p[p[z]]
	rb_node_t *uncle;//叔叔节点y
	rb_node_t *tmp;//临时节点
	
	while ((parent = node->parent) && parent->color == RED) {
		//parent 为node的父节点,1.判断父节点时候为空 2.若父节点不为空,判断父节点是否是红色
		gparent = parent->parent;
		
		if (parent == gparent->left) { //当祖父的左孩子即为父母时
			uncle = gparent->right;//定义叔叔的概念 ,叔叔就是父母的右孩子

			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了
				//z的父母p[z]染黑
				//原祖父节点染红
				//
				parent->color = BLACK;
				gparent->color = RED;
				root = rb_rotate_right(gparent, root);//右旋[节点z,与祖父节点]
			}
		}else { //当祖父的右孩子是父母时
			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; //返回根节点
}
Пример #21
0
//红黑树修复删除的4中情况
//x表示要删除的节点,*other, w表示兄弟节点
static rb_node_t *rb_erase_rebalance(rb_node_t *node, rb_node_t *parent, rb_node_t *root)
{
	rb_node_t *other; //x的兄弟other
	rb_node_t *o_left; //兄弟的左孩子
	rb_node_t *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->黑色 , x的父节点染红
				root = rb_rotate_left(parent, root);//在以x的父节点做一次左旋
				other = parent->right;
			}

			if ((!other->left || other->left->color == BLACK) &&
						(!other->right || other->right->color == BLACK)) { // 情况2:x的兄弟w是黑色的,且w的两个孩子都是黑色的
				other->color = RED;// 兄弟w变成为红色
				node = parent; //父节点为新节点node
				parent = node->parent; // 
			}else {
				if (!other->right ||  other->right->color == BLACK) { //情况3:x的兄弟w是黑色的,且,w的左孩子是红色,右孩子是黑色的
					if ((o_left = other->left)) {
						o_left->color = BLACK;
					}

					other->color = RED;
					root = rb_rotate_right(other, root);
					other = parent->right;
				}
				//情况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;
	}
	return root;
}
Пример #22
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;
    }
  }
}
Пример #23
0
static void rbtree_remove(char *node, char **tree)
{
    char *parent = rb_get_parent(node);
    char *left = rbtree_get_left(node);
    char *right = rbtree_get_right(node);
    char *next;
    int color;

    if (!left)
        next = right;
    else if (!right)
        next = left;
    else
        next = rbtree_first(right);

    if (parent)
        rb_set_child(next, parent, rbtree_get_left(parent) == node);
    else
        *tree = next;

    if (left && right) {
        color = rb_get_color(next);
        rb_set_color(rb_get_color(node), next);

        rb_set_left(left, next);
        rb_set_parent(next, left);

        if (next != right) {
            parent = rb_get_parent(next);
            rb_set_parent(rb_get_parent(node), next);

            node = rbtree_get_right(next);
            rb_set_left(node, parent);

            rb_set_right(right, next);
            rb_set_parent(next, right);
        } else {
            rb_set_parent(parent, next);
            parent = next;
            node = rbtree_get_right(next);
        }
    } else {
        color = rb_get_color(node);
        node = next;
    }
    /*
     * 'node' is now the sole successor's child and 'parent' its
     * new parent (since the successor can have been moved).
     */
    if (node)
        rb_set_parent(parent, node);

    /*
     * The 'easy' cases.
     */
    if (color == RB_RED)
        return;
    if (node && rb_is_red(node)) {
        rb_set_color(RB_BLACK, node);
        return;
    }

    do {
        if (node == *tree)
            break;

        if (node == rbtree_get_left(parent)) {
            char *sibling = rbtree_get_right(parent);

            if (rb_is_red(sibling)) {
                rb_set_color(RB_BLACK, sibling);
                rb_set_color(RB_RED, parent);
                rb_rotate_left(parent, tree);
                sibling = rbtree_get_right(parent);
            }
            if ((!rbtree_get_left(sibling)  || rb_is_black(rbtree_get_left(sibling))) &&
                (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling)))) {
                rb_set_color(RB_RED, sibling);
                node = parent;
                parent = rb_get_parent(parent);
                continue;
            }
            if (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling))) {
                rb_set_color(RB_BLACK, rbtree_get_left(sibling));
                rb_set_color(RB_RED, sibling);
                rb_rotate_right(sibling, tree);
                sibling = rbtree_get_right(parent);
            }
            rb_set_color(rb_get_color(parent), sibling);
            rb_set_color(RB_BLACK, parent);
            rb_set_color(RB_BLACK, rbtree_get_right(sibling));
            rb_rotate_left(parent, tree);
            node = *tree;
            break;
        } else {
            char *sibling = rbtree_get_left(parent);

            if (rb_is_red(sibling)) {
                rb_set_color(RB_BLACK, sibling);
                rb_set_color(RB_RED, parent);
                rb_rotate_right(parent, tree);
                sibling = rbtree_get_left(parent);
            }
            if ((!rbtree_get_left(sibling)  || rb_is_black(rbtree_get_left(sibling))) &&
                (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling)))) {
                rb_set_color(RB_RED, sibling);
                node = parent;
                parent = rb_get_parent(parent);
                continue;
            }
            if (!rbtree_get_left(sibling) || rb_is_black(rbtree_get_left(sibling))) {
                rb_set_color(RB_BLACK, rbtree_get_right(sibling));
                rb_set_color(RB_RED, sibling);
                rb_rotate_left(sibling, tree);
                sibling = rbtree_get_left(parent);
            }
            rb_set_color(rb_get_color(parent), sibling);
            rb_set_color(RB_BLACK, parent);
            rb_set_color(RB_BLACK, rbtree_get_left(sibling));
            rb_rotate_right(parent, tree);
            node = *tree;
            break;
        }
    } while (rb_is_black(node));

    if (node)
        rb_set_color(RB_BLACK, node);
}
Пример #24
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;
}
Пример #25
0
/*
 * rb_insert - insert node into Red-black tree
 */
static void rb_insert(void *node){
    void *parent, *child, *sib;

    RB_LEFT(node) = RB_RIGHT(node) = rb_null;
    parent = rb_root;
    child = RB_LEFT(rb_root);
    while(child != rb_null){
        parent = child;
        if(CUR_SIZE_MASKED(child) > CUR_SIZE_MASKED(node)){
            child = RB_LEFT(child);
        }else if(CUR_SIZE_MASKED(child) == CUR_SIZE_MASKED(node)){
            if(child > node){
                child = RB_LEFT(child);
            }else{
                child = RB_RIGHT(child);
            }
        }else{
            child = RB_RIGHT(child);
        }
    }
    RB_PARENT(node) = parent;
    if(parent == rb_root || CUR_SIZE_MASKED(parent) > CUR_SIZE_MASKED(node)){
        RB_LEFT(parent) = node;
    }else if(CUR_SIZE_MASKED(parent) == CUR_SIZE_MASKED(node)){
        if(parent > node){
            RB_LEFT(parent) = node;
        }else{
            RB_RIGHT(parent) = node;
        }
    }else{
        RB_RIGHT(parent) = node;
    }

    RB_RED(node) = 1;
    while(RB_RED(RB_PARENT(node))){
        if(RB_PARENT(node) == RB_LEFT(RB_PARENT(RB_PARENT(node)))){
            sib = RB_RIGHT(RB_PARENT(RB_PARENT(node)));
            if(RB_RED(sib)){
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(sib) = 0;
                RB_RED(RB_PARENT(RB_PARENT(node))) = 1;
                node = RB_PARENT(RB_PARENT(node));
            }else{
                if(node == RB_RIGHT(RB_PARENT(node))){
                    node = RB_PARENT(node);
                    rb_rotate_left(node);
                }
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(RB_PARENT(RB_PARENT(node))) = 1;
                rb_rotate_right(RB_PARENT(RB_PARENT(node)));
            }
        }else{
            sib = RB_LEFT(RB_PARENT(RB_PARENT(node)));
            if(RB_RED(sib)){
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(sib) = 0;
                RB_RED(RB_PARENT(RB_PARENT(node))) = 1;
                node = RB_PARENT(RB_PARENT(node));
            }else{
                if(node == RB_LEFT(RB_PARENT(node))){
                    node = RB_PARENT(node);
                    rb_rotate_right(node);
                }
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(RB_PARENT(RB_PARENT(node))) = 1;
                rb_rotate_left(RB_PARENT(RB_PARENT(node)));
            }
        }
    }
    RB_RED(RB_LEFT(rb_root)) = 0;
}
Пример #26
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;
}
Пример #27
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;
}
Пример #28
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);
}