Пример #1
0
/*
 * Fixup required to delete an internal node, rotating left-leaning red links to the right.
 *
 * Parameters:
 * - ptn = Pointer to root of subtree to be fixed up.
 *
 * Returns:
 * Pointer to root of subtree after fixup.
 */
static PRBTREENODE move_red_right(PRBTREENODE ptn)
{
    color_flip(ptn);
    if (ptn->ptnLeft && rbtIsRed(ptn->ptnLeft->ptnLeft))
    {
        ptn = rotate_right(ptn);
        color_flip(ptn);
    }
    return ptn;
}
Пример #2
0
/*
 * Fixup required to delete the leftmost node; we maintain the invariant that either the current node
 * or its left child is red.  After a color flip, we resolve any successive reds on the right with rotations
 * and another color flip.
 *
 * Parameters:
 * - ptn = Pointer to root of subtree to be fixed up.
 *
 * Returns:
 * Pointer to root of subtree after fixup.
 */
static PRBTREENODE move_red_left(PRBTREENODE ptn)
{
    color_flip(ptn);
    if (rbtNodeRight(ptn) && rbtIsRed(rbtNodeRight(ptn)->ptnLeft))
    {
        rbtSetNodeRight(ptn, rotate_right(rbtNodeRight(ptn)));
        ptn = rotate_left(ptn);
        color_flip(ptn);
    }
    return ptn;
}
Пример #3
0
static void insert_fix_up(rbtree_t rb,struct rbnode *n)
{
	while(n->parent->color == RED)
	{
		struct rbnode *parent = n->parent;
		struct rbnode *grand_parent = parent->parent;
		if(parent == grand_parent->left)
		{
			struct rbnode *ancle = grand_parent->right;
			if(ancle->color == RED)
			{
				color_flip(grand_parent);
				n = grand_parent;
			}
			else
			{
				if(n == parent->right)
				{
					n = parent;
					rotate_left(rb,n);
				}

				n->parent->color = BLACK;
				n->parent->parent->color = RED;
				rotate_right(rb,n->parent->parent);
			}
		}
		else
		{
			struct rbnode *ancle = grand_parent->left;
			if(ancle->color == RED)
			{
				color_flip(grand_parent);
				n = grand_parent;
			}
			else
			{
				if(n == parent->left)
				{
					n = parent;
					rotate_right(rb,n);
				}
				n->parent->color = BLACK;
				n->parent->parent->color = RED;
				rotate_left(rb,n->parent->parent);
			}
		}
	}
	rb->root->color = BLACK;
}
Пример #4
0
struct rbtree *rb_insert(struct rbtree *tree, struct rbtree *node)
{
    node->left = node->right = NULL;
    node->red = false;

    if (!tree) {
        node->red = true;
        return node;
    }

    if (is_red(tree->left) && is_red(tree->right))
        color_flip(tree);

    if (node->key < tree->key)
        tree->left = rb_insert(tree->left, node);
    else
        tree->right = rb_insert(tree->right, node);

    if (is_red(tree->right))
        tree = rotate_left(tree);

    if (is_red(tree->left) && is_red(tree->left->left))
        tree = rotate_right(tree);

    return tree;
}
Пример #5
0
/*
 * Fixes up the given subtree after an insertion or deletion, to ensure that it maintains the invariants
 * that no two consecutive links in the tree may be red, and that all red links must lean left.
 *
 * Parameters:
 * - ptn = Pointer to the root node of the subtree to be fixed up.
 *
 * Returns:
 * Pointer to the new root node of the subtree after fixup is performed.
 */
static PRBTREENODE fix_up(PRBTREENODE ptn)
{
    if (rbtIsRed(rbtNodeRight(ptn)) && !rbtIsRed(ptn->ptnLeft))
        ptn = rotate_left(ptn);
    if (rbtIsRed(ptn->ptnLeft) && rbtIsRed(ptn->ptnLeft->ptnLeft))
        ptn = rotate_right(ptn);
    if (rbtIsRed(ptn->ptnLeft) && rbtIsRed(rbtNodeRight(ptn)))
        color_flip(ptn);
    return ptn;
}