Exemplo n.º 1
0
/* insert may violate the rbtree properties, fix up the tree */
void rbtree_insert_fixup(util_rbtree_t *rbtree, util_rbtree_node_t *node)
{
    util_rbtree_node_t *p, *u; /* u is the uncle node of node */
    while(util_rbt_isred(node->parent) && (node !=rbtree->root ))
    {
        p = node->parent;
        if(p == p->parent->left) /* parent is the left child */
        {
            u = p->parent->right;
            if(util_rbt_isred(u)) /* case 1: p & u are red */
            {
                util_rbt_black(u);
                util_rbt_black(p);
                util_rbt_red(p->parent);
                node = p->parent;
            }
            else
            {
                if(node == p->right) /* case 2: p:read, u:black, node is right child */
                {
                    node = p;
                    rbtree_left_rotate(rbtree, node); 
                    p = node->parent;
                }
                /* case 3: p:read, u:black, node is left child */
                util_rbt_black(p);
                util_rbt_red(p->parent);
                rbtree_right_rotate(rbtree, p->parent);
            }
        }
        else /* parent is the right child */
        {
            u = p->parent->left;
			if(util_rbt_isred(u))
			{
				util_rbt_black(u);
				util_rbt_black(p);
				util_rbt_red(p->parent);
                node = p->parent;
			}
			else
			{
				if(p->left == node)
				{
					node = p;
					rbtree_right_rotate(rbtree, node);
					p = node->parent;
				}
				util_rbt_black(p);
				util_rbt_red(p->parent);
				rbtree_left_rotate(rbtree, p->parent);
			}
        }
    }
    /* mark root to black */
    util_rbt_black(rbtree->root);
}
Exemplo n.º 2
0
static void rbtree_remove_fixup(rbtree_t *tree, rbtree_node_t *node)
{
  rbtree_node_t *brother;
  while (node != tree->root && rbtree_is_black(node)) {
    if (node == node->parent->left) {
      brother = node->parent->right;
      if (rbtree_is_red(brother)) {
	rbtree_color_swap(node->parent, brother);
	rbtree_left_rotate(tree, node->parent);
	brother = node->parent->right;
      }
      if (rbtree_is_black(brother->left) &&
	  rbtree_is_black(brother->right)) {
	rbtree_set_red(brother);
	node = node->parent;
      } else {
	if (rbtree_is_black(brother->right)) {
	  rbtree_color_swap(brother, brother->left);
	  rbtree_right_rotate(tree, brother);
	  brother = node->parent->right;
	}
	rbtree_set_black(brother->right);
	rbtree_color_swap(node->parent, brother);
	rbtree_left_rotate(tree, node->parent);
	node = tree->root;
      }
    } else {
      brother = node->parent->left;
      if (rbtree_is_red(brother)) {
	rbtree_color_swap(node->parent, brother);
	rbtree_right_rotate(tree, node->parent);
	brother = node->parent->left;
      }
      if (rbtree_is_black(brother->left) &&
	  rbtree_is_black(brother->right)) {
	rbtree_set_red(brother);
	node = node->parent;
      } else {
	if (rbtree_is_black(brother->left)) {
	  rbtree_color_swap(brother, brother->right);
	  rbtree_left_rotate(tree, brother);
	  brother = node->parent->left;
	}
	rbtree_set_black(brother->left);
	rbtree_color_swap(node->parent, brother);
	rbtree_right_rotate(tree, node->parent);
	node = tree->root;
      }
    }
  }
  rbtree_set_black(node);
}
Exemplo n.º 3
0
void rbtree_insert(volatile rbtree_t *tree,rbtree_node_t *node){
	rbtree_node_t **root,*temp,*sentinel;

	root = (rbtree_node_t **)&tree -> root;
	sentinel = tree -> sentinel;
	if(*root == sentinel){
		node -> parent = NULL;
		node -> left = sentinel;
		node -> right = sentinel;
		rbt_black(node);
		*root = node;
		return;
	}
	tree -> insert(*root,node,sentinel);
	/*re_balance tree*/
	while(node != *root && rbt_is_red(node -> parent)){
		if(node -> parent == node -> parent -> parent -> left){
			temp = node -> parent -> parent -> right;
			if(rbt_is_red(temp)){
				rbt_black(node -> parent);
				rbt_black(temp);
				rbt_red(node -> parent -> parent);
				node = node -> parent -> parent;
			}else{
				if(node == node -> parent -> right){
					node = node -> parent;
					rbtree_left_rotate(root,sentinel,node);
				}
				rbt_black(node -> parent);
				rbt_red(node -> parent -> parent);
				rbtree_right_rotate(root,sentinel,node -> parent -> parent);
			}
		}else{
			temp = node -> parent -> parent -> left;
			if(rbt_is_red(temp)){
				rbt_black(node -> parent);
				rbt_black(temp);
				rbt_red(node -> parent -> parent);
				node = node -> parent -> parent;
			}else{
				if(node == node -> parent -> left){
					node = node -> parent;
					rbtree_right_rotate(root,sentinel,node);
				}
				rbt_black(node -> parent);
				rbt_red(node -> parent -> parent);
				rbtree_left_rotate(root,sentinel,node -> parent -> parent);
			}
		}
	}
	rbt_black(*root);
}
Exemplo n.º 4
0
static void rbtree_insert_fixup(rbtree_t *tree, rbtree_node_t *node)
{
  while (rbtree_is_red(node->parent)) {
    if (node->parent == node->parent->parent->left) {
      if (rbtree_is_red(node->parent->parent->right)) {
	rbtree_set_black(node->parent);
	rbtree_set_black(node->parent->parent->right);
	rbtree_set_red(node->parent->parent);
	node = node->parent->parent;
      } else {
	if (node == node->parent->right) {
	  node = node->parent;
	  rbtree_left_rotate(tree, node);
	}
	rbtree_set_black(node->parent);
	rbtree_set_red(node->parent->parent);
	rbtree_right_rotate(tree, node->parent->parent);
      }
    } else {
      if (rbtree_is_red(node->parent->parent->left)) {
	rbtree_set_black(node->parent);
	rbtree_set_black(node->parent->parent->left);
	rbtree_set_red(node->parent->parent);
      } else {
	if (node == node->parent->left) {
	  node = node->parent;
	  rbtree_right_rotate(tree, node);
	}
	rbtree_set_black(node->parent);
	rbtree_set_red(node->parent->parent);
	rbtree_left_rotate(tree, node->parent->parent);
      }
    }
  }
  rbtree_set_black(tree->root);
}
Exemplo n.º 5
0
void
rbtree_delete( rbtree_t *tree , rbtree_node_t *node )
{
	uint_t red;
	rbtree_node_t **root,*sentinel,*subst,*temp,*w;
	
	/* a binary tree delete */

	root = (rbtree_node_t **) &tree->root;
	sentinel = tree->sentinel;
	
	if (node->left == sentinel)
	{
		temp = node->right;
		subst = node;
		
	}
	else if (node->right == sentinel)
	{
		temp = node->left;
		subst = node;
		
	}
	else
	{
		subst = rbtree_min( node->right , sentinel );
		
		if (subst->left != sentinel)
		{
			temp = subst->left;
		}
		else
		{
			temp = subst->right;
		}
	}
	
	if (subst == *root)
	{
		*root = temp;
		rbt_black( temp );
		
		/* DEBUG stuff */
		node->left = NULL;
		node->right = NULL;
		node->parent = NULL;
		node->key = 0;
		
		return;
	}
	
	red = rbt_is_red(subst);
	
	if (subst == subst->parent->left)
	{
		subst->parent->left = temp;
		
	}
	else
	{
		subst->parent->right = temp;
	}
	
	if (subst == node)
	{
		
		temp->parent = subst->parent;
		
	}
	else
	{
		
		if (subst->parent == node)
		{
			temp->parent = subst;
			
		}
		else
		{
			temp->parent = subst->parent;
		}
		
		subst->left = node->left;
		subst->right = node->right;
		subst->parent = node->parent;
		rbt_copy_color( subst , node );
		
		if (node == *root)
		{
			*root = subst;
			
		}
		else
		{
			if (node == node->parent->left)
			{
				node->parent->left = subst;
			}
			else
			{
				node->parent->right = subst;
			}
		}
		
		if (subst->left != sentinel)
		{
			subst->left->parent = subst;
		}
		
		if (subst->right != sentinel)
		{
			subst->right->parent = subst;
		}
	}
	
	/* DEBUG stuff */
	node->left = NULL;
	node->right = NULL;
	node->parent = NULL;
	node->key = 0;
	
	if (red)
	{
		return;
	}
	
	/* a delete fixup */

	while (temp != *root && rbt_is_black(temp) )
			{
		
		if (temp == temp->parent->left)
		{
			w = temp->parent->right;
			
			if (rbt_is_red(w) )
					{
				rbt_black( w );
				rbt_red( temp->parent );
				rbtree_left_rotate( root , sentinel , temp->parent );
				w = temp->parent->right;
			}
			
			if (rbt_is_black(w->left) && rbt_is_black(w->right) )
					{
				rbt_red( w );
				temp = temp->parent;
				
			}
			else
			{
				if (rbt_is_black(w->right) )
						{
					rbt_black( w->left );
					rbt_red( w );
					rbtree_right_rotate( root , sentinel , w );
					w = temp->parent->right;
				}
				
				rbt_copy_color( w , temp->parent );
				rbt_black( temp->parent );
				rbt_black( w->right );
				rbtree_left_rotate( root , sentinel , temp->parent );
				temp = *root;
			}
			
		}
		else
		{
			w = temp->parent->left;
			
			if (rbt_is_red(w) )
					{
				rbt_black( w );
				rbt_red( temp->parent );
				rbtree_right_rotate( root , sentinel , temp->parent );
				w = temp->parent->left;
			}
			
			if (rbt_is_black(w->left) && rbt_is_black(w->right) )
					{
				rbt_red( w );
				temp = temp->parent;
				
			}
			else
			{
				if (rbt_is_black(w->left) )
						{
					rbt_black( w->right );
					rbt_red( w );
					rbtree_left_rotate( root , sentinel , w );
					w = temp->parent->left;
				}
				
				rbt_copy_color( w , temp->parent );
				rbt_black( temp->parent );
				rbt_black( w->left );
				rbtree_right_rotate( root , sentinel , temp->parent );
				temp = *root;
			}
		}
	}

	rbt_black( temp );
}
Exemplo n.º 6
0
	    struct rbtree *rbtree_fixup_add(struct rbtree *root, struct rbtree *node)
	     {
			 struct rbtree *uncle;
			 
			 //Текущий узел красного цвета(RED)
			 while (node != root && node -> parent -> color == COLOR_RED)
			 
			 {
				 if (node -> parent == node -> parent -> parent ->left)
				 {
					
					//Узел в дереве слева дедушки
					uncle = node -> parent -> parent -> right;
					
					if (uncle -> color == COLOR_RED){
						
						// Шаг 1 - Дядя Красный (RED)
						node -> parent ->color = COLOR_BLACK;
				        uncle -> color = COLOR_BLACK;
				        node -> parent -> parent -> color = COLOR_RED;
				        node = node -> parent -> parent;
				        
					} else {
						// Шаг 2-3 - Дядя Черный (BLACK)
						if (node == node -> parent -> right){
							
							
							//возаврат назад на шаги 2-3
						    node = node -> parent;
						    root = rbtree_left_rotate(root, node -> parent -> parent); 
						}
                        // Шаг 3
                        node -> parent -> color = COLOR_BLACK;
                        node -> parent -> parent -> color = COLOR_RED;
                        root = rbtree_right_rotate(root, node -> parent -> parent);
					}
					 
				 } else {
					 /* Узел в правом дереве деда
					  * Шаги 4-5-6
				  * Узел в правом дереве деда
					  */

                 uncle = node -> parent -> parent -> left;
                 if (uncle -> color == COLOR_RED){
					 // Дядя является красным - Шаг 4
					 node -> parent -> color = COLOR_BLACK;
					 uncle -> color = COLOR_BLACK;
					 node -> parent -> parent -> color = COLOR_RED;
					 node  = node -> parent -> parent;
				 }else {
					 
					 // Дядя черный
				if (node == node -> parent ->left){
					node = node -> parent;
					root = rbtree_right_rotate(root, node);
					
				}
				
	             node -> parent -> color = COLOR_BLACK;
	             node -> parent -> parent -> color = COLOR_RED;
	             root = rbtree_left_rotate(root, node -> parent -> parent);
	             
			 }
		}			  
	}				 
    root -> color = COLOR_BLACK;
    return root;
}
Exemplo n.º 7
0
void
rbtree_delete(struct rbtree *tree, struct rbnode *node)
{
    struct rbnode **root = &tree->root;
    struct rbnode *sentinel = tree->sentinel;
    struct rbnode *subst, *temp, *w;
    uint8_t red;

    /* a binary tree delete */

    if (node->left == sentinel) {
        temp = node->right;
        subst = node;
    } else if (node->right == sentinel) {
        temp = node->left;
        subst = node;
    } else {
        subst = rbtree_node_min(node->right, sentinel);
        if (subst->left != sentinel) {
            temp = subst->left;
        } else {
            temp = subst->right;
        }
    }

    if (subst == *root) {
        *root = temp;
        rbtree_black(temp);

        rbtree_node_init(node);

        return;
    }

    red = rbtree_is_red(subst);

    if (subst == subst->parent->left) {
        subst->parent->left = temp;
    } else {
        subst->parent->right = temp;
    }

    if (subst == node) {
        temp->parent = subst->parent;
    } else {

        if (subst->parent == node) {
            temp->parent = subst;
        } else {
            temp->parent = subst->parent;
        }

        subst->left = node->left;
        subst->right = node->right;
        subst->parent = node->parent;
        rbtree_copy_color(subst, node);

        if (node == *root) {
            *root = subst;
        } else {
            if (node == node->parent->left) {
                node->parent->left = subst;
            } else {
                node->parent->right = subst;
            }
        }

        if (subst->left != sentinel) {
            subst->left->parent = subst;
        }

        if (subst->right != sentinel) {
            subst->right->parent = subst;
        }
    }

    rbtree_node_init(node);

    if (red) {
        return;
    }

    /* a delete fixup */

    while (temp != *root && rbtree_is_black(temp)) {

        if (temp == temp->parent->left) {
            w = temp->parent->right;

            if (rbtree_is_red(w)) {
                rbtree_black(w);
                rbtree_red(temp->parent);
                rbtree_left_rotate(root, sentinel, temp->parent);
                w = temp->parent->right;
            }

            if (rbtree_is_black(w->left) && rbtree_is_black(w->right)) {
                rbtree_red(w);
                temp = temp->parent;
            } else {
                if (rbtree_is_black(w->right)) {
                    rbtree_black(w->left);
                    rbtree_red(w);
                    rbtree_right_rotate(root, sentinel, w);
                    w = temp->parent->right;
                }

                rbtree_copy_color(w, temp->parent);
                rbtree_black(temp->parent);
                rbtree_black(w->right);
                rbtree_left_rotate(root, sentinel, temp->parent);
                temp = *root;
            }

        } else {
            w = temp->parent->left;

            if (rbtree_is_red(w)) {
                rbtree_black(w);
                rbtree_red(temp->parent);
                rbtree_right_rotate(root, sentinel, temp->parent);
                w = temp->parent->left;
            }

            if (rbtree_is_black(w->left) && rbtree_is_black(w->right)) {
                rbtree_red(w);
                temp = temp->parent;
            } else {
                if (rbtree_is_black(w->left)) {
                    rbtree_black(w->right);
                    rbtree_red(w);
                    rbtree_left_rotate(root, sentinel, w);
                    w = temp->parent->left;
                }

                rbtree_copy_color(w, temp->parent);
                rbtree_black(temp->parent);
                rbtree_black(w->left);
                rbtree_right_rotate(root, sentinel, temp->parent);
                temp = *root;
            }
        }
    }

    rbtree_black(temp);
}
Exemplo n.º 8
0
void
rbtree_insert(struct rbtree *tree, struct rbnode *node)
{
    struct rbnode **root = &tree->root;
    struct rbnode *sentinel = tree->sentinel;
    struct rbnode *temp, **p;

    /* empty tree */

    if (*root == sentinel) {
        node->parent = NULL;
        node->left = sentinel;
        node->right = sentinel;
        rbtree_black(node);
        *root = node;
        return;
    }

    /* a binary tree insert */

    temp = *root;
    for (;;) {

        p = (node->key < temp->key) ? &temp->left : &temp->right;
        if (*p == sentinel) {
            break;
        }
        temp = *p;
    }

    *p = node;
    node->parent = temp;
    node->left = sentinel;
    node->right = sentinel;
    rbtree_red(node);

    /* re-balance tree */

    while (node != *root && rbtree_is_red(node->parent)) {

        if (node->parent == node->parent->parent->left) {
            temp = node->parent->parent->right;

            if (rbtree_is_red(temp)) {
                rbtree_black(node->parent);
                rbtree_black(temp);
                rbtree_red(node->parent->parent);
                node = node->parent->parent;
            } else {
                if (node == node->parent->right) {
                    node = node->parent;
                    rbtree_left_rotate(root, sentinel, node);
                }

                rbtree_black(node->parent);
                rbtree_red(node->parent->parent);
                rbtree_right_rotate(root, sentinel, node->parent->parent);
            }
        } else {
            temp = node->parent->parent->left;

            if (rbtree_is_red(temp)) {
                rbtree_black(node->parent);
                rbtree_black(temp);
                rbtree_red(node->parent->parent);
                node = node->parent->parent;
            } else {
                if (node == node->parent->left) {
                    node = node->parent;
                    rbtree_right_rotate(root, sentinel, node);
                }

                rbtree_black(node->parent);
                rbtree_red(node->parent->parent);
                rbtree_left_rotate(root, sentinel, node->parent->parent);
            }
        }
    }

    rbtree_black(*root);
}
Exemplo n.º 9
0
/* delete may violate the rbtree properties, fix up the tree */
void rbtree_delete_fixup(util_rbtree_t *rbtree, util_rbtree_node_t *node)
{
    int h = 0;
    util_rbtree_node_t *w;
	while((node != rbtree->root) && util_rbt_isblack(node))
	{
        h++;
        if(node == node->parent->left) /* node is left child */
        {
            w = node->parent->right;
            if(util_rbt_isred(w))
            {
                util_rbt_black(w);
                util_rbt_red(node->parent);
                rbtree_left_rotate(rbtree, node->parent);
                w = node->parent->right;
            }
            if(util_rbt_isblack(w->left) && util_rbt_isblack(w->right))
            {
                util_rbt_red(w);
                node = node->parent;
            }
            else
            {
                if(util_rbt_isblack(w->right))
                {
                    util_rbt_black(w->left);
                    util_rbt_red(w);
                    rbtree_right_rotate(rbtree, w);
                    w = node->parent->right;
                }
                w->color = node->parent->color;
                util_rbt_black(node->parent);
                util_rbt_black(w->right);
                rbtree_left_rotate(rbtree, node->parent);
                node = rbtree->root; /* to break loop */
            }
        }
        else /* node is right child */
        {
            w = node->parent->left;
            if(w == 0)
            {
                //FIXME:
                //int t = 4;
            }
            if(util_rbt_isred(w))
            {
                util_rbt_black(w);
                util_rbt_red(node->parent);
                rbtree_right_rotate(rbtree, node->parent);
                w = node->parent->left;
            }
            if(util_rbt_isblack(w->left) && util_rbt_isblack(w->right))
            {
                util_rbt_red(w);
                node = node->parent;
            }
            else
            {
                if(util_rbt_isblack(w->left))
                {
                    util_rbt_black(w->right);
                    util_rbt_red(w);
                    rbtree_left_rotate(rbtree, w);
                    w = node->parent->left;
                }
                w->color = node->parent->color;
                util_rbt_black(node->parent);
                util_rbt_black(w->left);
                rbtree_right_rotate(rbtree, node->parent);
                node = rbtree->root; /* to break loop */
            }
        }
	}
    util_rbt_black(node);
}
Exemplo n.º 10
0
void rbtree_insert(ezRBTree *tree, ezRBTreeNode *node) {
    ezRBTreeNode **root, *temp, *sentinel;

    /* a binary tree insert */
    root = (ezRBTreeNode **) &tree->root;
    sentinel = tree->sentinel;

    if (*root == sentinel) {
        node->parent = NULL;
        node->left = sentinel;
        node->right = sentinel;
        rbt_black(node);
        *root = node;

        return;
    }

    default_rbtree_insert_value(tree, *root, node, sentinel);

    /* re-balance tree */
    while (node != *root && rbt_is_red(node->parent)) {

        if (node->parent == node->parent->parent->left) {
            temp = node->parent->parent->right;

            if (rbt_is_red(temp)) {
                rbt_black(node->parent);
                rbt_black(temp);
                rbt_red(node->parent->parent);
                node = node->parent->parent;

            } else {
                if (node == node->parent->right) {
                    node = node->parent;
                    rbtree_left_rotate(root, sentinel, node);
                }

                rbt_black(node->parent);
                rbt_red(node->parent->parent);
                rbtree_right_rotate(root, sentinel, node->parent->parent);
            }

        } else {
            temp = node->parent->parent->left;

            if (rbt_is_red(temp)) {
                rbt_black(node->parent);
                rbt_black(temp);
                rbt_red(node->parent->parent);
                node = node->parent->parent;

            } else {
                if (node == node->parent->left) {
                    node = node->parent;
                    rbtree_right_rotate(root, sentinel, node);
                }

                rbt_black(node->parent);
                rbt_red(node->parent->parent);
                rbtree_left_rotate(root, sentinel, node->parent->parent);
            }
        }
    }

    rbt_black(*root);
}
Exemplo n.º 11
0
/*
 * 红黑树删除修正函数
 *
 * 在从红黑树中删除插入节点之后(红黑树失去平衡),再调用该函数;
 * 目的是将它重新塑造成一颗红黑树。
 *
 * 参数说明:
 *     root 红黑树的根
 *     node 待修正的节点
 */
static void rbtree_delete_fixup(RBRoot *root, Node *node, Node *parent)
{
    Node *other;

    while ((!node || rb_is_black(node)) && node != root->node)
    {
        if (parent->left == node)
        {
            //1.         parent                     parent.r                     old.ohter.b         
            //           /     \                   /        \                    /         \
            //       child.b    other.r         child.b    other.b           parent.r       d
            //        /   \    /      \         /     \    /     \           /       \
            //       a     b  c        d       a     b     c      d       child.b     c  <- new.other
            //                                                            /     \
            //                                                           a       b
            other = parent->right;                    
            if (rb_is_red(other))
            {
                // Case 1: x的兄弟w是红色的  
                rb_set_black(other);
                rb_set_red(parent);
                rbtree_left_rotate(root, parent);
                other = parent->right;
            }
			//2.       gparent                     gparent         3. <- new.parent
			//           |
			//         parent                      parent          2. <- new.child
			//        /      \                    /      \
			//   child.b     other         old.child.b    other.r  1. <- color = RED
			//   /     \     /    \
			//  a      b    c.b  d.b    

            if ((!other->left || rb_is_black(other->left)) &&
                (!other->right || rb_is_black(other->right)))
            {
                // Case 2: x的兄弟w是黑色,且w的俩个孩子也都是黑色的  
                rb_set_red(other);
                node = parent;
                parent = rb_parent(node);
            }
            else
            {   
                if (!other->right || rb_is_black(other->right))
                {
			//3.1         parent                  parent                                            parent
			//           /      \                /      \                                          /        \
			//     child.b     other.b     child.b      other.r      <- color RED           child.b        c.b                 <- new.other
			//     /    \      /     \      /  \         /    \                              /   \            \
			//    a      b    c      d.b   a   b       c.b     d.b   <- c.color BLACK        a    b           old.other.r
			//                                                                                                /        \
			//                                                                                                         d.b
                    // Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。  
                    rb_set_black(other->left);
                    rb_set_red(other);
                    rbtree_right_rotate(root, other);
                    other = parent->right;
                }
			//3.2       parent.c                parent.b          2<- color BLACK                       other.b
			//         /      \                /        \                                             /       \
			//    child.b    other.b         child.b    other.c   1<- color parent.color         parent.b      d.b
			//    /    \     /      \        /     \    /     \                                 /     \
			//   a     b    c       d.r    a      b     c     d.b 3<- color BLACK            child.b    c
			//                                                                              /     \
			//                                                                             a       b
                // Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
                rb_set_color(other, rb_color(parent));
                rb_set_black(parent);
                rb_set_black(other->right);
                rbtree_left_rotate(root, parent);
                node = root->node;
                break;
            }
        }
        else
        {
            other = parent->left;
            if (rb_is_red(other))
            {
                // Case 1: x的兄弟w是红色的  
                rb_set_black(other);
                rb_set_red(parent);
                rbtree_right_rotate(root, parent);
                other = parent->left;
            }
            if ((!other->left || rb_is_black(other->left)) &&
                (!other->right || rb_is_black(other->right)))
            {
                // Case 2: x的兄弟w是黑色,且w的俩个孩子也都是黑色的  
                rb_set_red(other);
                node = parent;
                parent = rb_parent(node);
            }
            else
            {
                if (!other->left || rb_is_black(other->left))
                {
                    // Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。  
                    rb_set_black(other->right);
                    rb_set_red(other);
                    rbtree_left_rotate(root, other);
                    other = parent->left;
                }
                // Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
                rb_set_color(other, rb_color(parent));
                rb_set_black(parent);
                rb_set_black(other->left);
                rbtree_right_rotate(root, parent);
                node = root->node;
                break;
            }
        }
    }
    if (node)
        rb_set_black(node);
}
Exemplo n.º 12
0
/*
 * 红黑树插入修正函数
 *
 * 在向红黑树中插入节点之后(失去平衡),再调用该函数;
 * 目的是将它重新塑造成一颗红黑树。
 *
 * 参数说明:
 *     root 红黑树的根
 *     node 插入的结点        // 对应《算法导论》中的z
 */
static void rbtree_insert_fixup(RBRoot *root, Node *node)
{
    Node *parent, *gparent;

    // 若“父节点存在,并且父节点的颜色是红色”
    while ((parent = rb_parent(node)) && rb_is_red(parent))
    {
        gparent = rb_parent(parent);

        //若“父节点”是“祖父节点的左孩子”
        if (parent == gparent->left)
        {
            // Case 1条件:叔叔节点是红色
            {
                Node *uncle = gparent->right;
                if (uncle && rb_is_red(uncle))
                {
                    rb_set_black(uncle);
                    rb_set_black(parent);
                    rb_set_red(gparent);
                    node = gparent;
                    continue;
                }
            }

            // Case 2条件:叔叔是黑色,且当前节点是右孩子
            if (parent->right == node)
            {
                Node *tmp;
                rbtree_left_rotate(root, parent);
                tmp = parent;
                parent = node;
                node = tmp;
            }

            // Case 3条件:叔叔是黑色,且当前节点是左孩子。
            rb_set_black(parent);
            rb_set_red(gparent);
            rbtree_right_rotate(root, gparent);
        } 
        else//若“z的父节点”是“z的祖父节点的右孩子”
        {
            // Case 1条件:叔叔节点是红色
            {
                Node *uncle = gparent->left;
                if (uncle && rb_is_red(uncle))
                {
                    rb_set_black(uncle);
                    rb_set_black(parent);
                    rb_set_red(gparent);
                    node = gparent;
                    continue;
                }
            }

            // Case 2条件:叔叔是黑色,且当前节点是左孩子
            if (parent->left == node)
            {
                Node *tmp;
                rbtree_right_rotate(root, parent);
                tmp = parent;
                parent = node;
                node = tmp;
            }

            // Case 3条件:叔叔是黑色,且当前节点是右孩子。
            rb_set_black(parent);
            rb_set_red(gparent);
            rbtree_left_rotate(root, gparent);
        }
    }

    // 将根节点设为黑色
    rb_set_black(root->node);
}