Exemplo n.º 1
0
static void
recolor(rbtree_t      *tree,
        rbtree_node_t *parent,
        rbtree_node_t *node)
{
  rbtree_node_t *sibling;

  while(is_black(node) && node != tree->root)
  {
    int left = (node == parent->child[LEFT]);

    sibling = parent->child[left];

    if(is_red(sibling))
    {
      set_black(sibling);
      set_red(parent);
      rbtree_rotate(tree, parent, left);
      sibling = parent->child[left];
    }

    if(is_black(sibling->child[LEFT]) && is_black(sibling->child[RIGHT]))
    {
      set_red(sibling);
      node = parent;
      parent = get_parent(node);
    }
    else
    {
      if(is_black(sibling->child[left]))
      {
        set_black(sibling->child[!left]);
        set_red(sibling);
        rbtree_rotate(tree, sibling, !left);
        sibling = parent->child[left];
      }

      if(is_black(parent))
        set_black(sibling);
      else
        set_red(sibling);
      set_black(parent);
      set_black(sibling->child[left]);

      rbtree_rotate(tree, parent, left);

      node = tree->root;
    }
  }

  if(node != NULL)
    set_black(node);
}
Exemplo n.º 2
0
/**
 * Rebalance the rbtree, so that no more than two RBTREE_COLOR_RED
 * nodes appear in a row.
 */
static void
c_rbtree_rebalance(struct c_rbtree_entry *node)
{
	struct c_rbtree_entry *parent, *grandfather, *uncle;

	while (node)
	{
		parent = node->rb_parent;
		grandfather = (parent ? parent->rb_parent : NULL);

		if (grandfather && parent == grandfather->rb_left)
			uncle = grandfather->rb_right;
		else if (grandfather && parent == grandfather->rb_right)
			uncle = grandfather->rb_left;

		/* If parent is black and we are red, we're fine. */
		if (parent->rb_color == RBTREE_COLOR_BLACK)
			return;

		if (uncle && uncle->rb_color == RBTREE_COLOR_RED)
		{
			parent->rb_color = RBTREE_COLOR_BLACK;
			uncle->rb_color = RBTREE_COLOR_BLACK;
			grandfather->rb_color = RBTREE_COLOR_RED;
			node = grandfather;
		}
		else
		{
			if (node == parent->rb_right &&
				parent == grandfather->rb_left)
			{
				rbtree_rotate(parent);
				node = node->rb_left;
				parent = node ? node->rb_parent : NULL;
				grandfather = parent ? parent->rb_parent : NULL;
			}
			else if (node == parent->rb_left &&
				parent == grandfather->rb_right)
			{
				rbtree_rotate(parent);
				node = node->rb_right;
				parent = node ? node->rb_parent : NULL;
				grandfather = parent ? parent->rb_parent : NULL;
			}

			node->rb_parent->rb_color = RBTREE_COLOR_BLACK;
			grandfather->rb_color = RBTREE_COLOR_RED;

			if (node == parent->rb_left &&
				parent == grandfather->rb_left)
				rbtree_rotate(grandfather);
			else if (node == parent->rb_right &&
				parent == grandfather->rb_right)
				rbtree_rotate(grandfather);

			return;
		}
	}

	return;
}