Пример #1
0
static void bst_insert_repair(bst *t, bstnode *n)
{
    bstnode *u;

    /* case 1: n is the root */
    if (!n->parent)
    {
        n->color = BLACK;
        return;
    }

    /* case 2: n's parent is black */
    if (n->parent->color == BLACK)
        return;

    /* case 3: n's uncle and father are both red */
    if ((u = UNCLE(n)) && u->color == RED)
    {
        n->parent->color = BLACK;
        u->color = BLACK;
        GRANDPARENT(n)->color = RED;
        bst_insert_repair(t, GRANDPARENT(n));
        return;
    }

    /* case 4: n has no or black uncle, red father and
        either  n = n->parent->right && n->parent = n->parent->parent->left
        or      n = n->parent->left  && n->parent = n->parent->parent->right
    */
    if (IS_RIGHT_CHILD(n) && IS_LEFT_CHILD(n->parent))
    {
        bst_rotate_left(t, n->parent);
        n = n->left;
    }
    else if (IS_LEFT_CHILD(n) && IS_RIGHT_CHILD(n->parent))
    {
        bst_rotate_right(t, n->parent);
        n = n->right;
    }

    /* case 5: n has no or black uncle, red father and
        either  n = n->parent->left  && n->parent = n->parent->parent->left
        or      n = n->parent->right && n->parent = n->parent->parent->right
    */
    n->parent->color = BLACK;
    GRANDPARENT(n)->color = RED;
    if (IS_LEFT_CHILD(n))
        bst_rotate_right(t, GRANDPARENT(n));
    else
    {
        bst_rotate_left(t, GRANDPARENT(n));
    }
}
Пример #2
0
static void bst_remove_at(bst *t, bstnode *n)
{
    bstnode *p;

    /* n has two children */
    if (!IS_LEAF(n->left) && !IS_LEAF(n->right))
    {
        static int del_from_left = 1;
        long tmpkey;
        void *tmpdata;
        if (del_from_left)
        {
            p = n->left;
            while (!IS_LEAF(p->right))
                p = p->right;
        }
        else
        {
            p = n->right;
            while (!IS_LEAF(p->left))
                p = p->left;
        }

        /* swap key and data and remove swapped node (which has 0 or 1 child) */
        tmpkey = p->key, p->key = n->key, n->key = tmpkey;
        tmpdata = p->data, p->data = n->data, n->data = tmpdata;
        bst_remove_at(t, p);
        return;
    }

    /* n has no/one child */
    p = IS_LEAF(n->left) ? n->right : n->left;

    /* replace n with p */
    p->parent = n->parent;
    if (n->parent)
    {
        if (IS_LEFT_CHILD(n))
            n->parent->left = p;
        else
            n->parent->right = p;
    }
    else
        t->root = p;

    if (IS_BLACK(n))
    {
        if (p->color == RED)
            p->color = BLACK;
        else
            bst_remove_repair(t, p);
    }
    free(n);
    return;
}
Пример #3
0
/* Rotate right helper function:
 *
 *              A
 *	      /    \
 *	     B     a
 *	   /   \
 *	   b    c
 *
 * Becomes :
 *             B
 *          /	  \
 *         A	   a
 *       /   \
 *      b     c
 *
 */
void rotate_right(struct node *x, struct node **root)
{
	struct node *y = x->p;
	if(IS_LEFT_CHILD(y))
		y->p->l = x;
	else
		y->p->r = x;
	x->p = y->p;
	y->l = x->r;
	y->l->p = y;
	x->r = y;
	y->p = x;

	/* Edge case, new x is the root?? */
	if (IS_NIL(x->p))
		*root = x;
}
Пример #4
0
static void bst_remove_repair(bst *t, bstnode *n)
{
    bstnode *sib;

    /* case 1: n is root */
    if (!n->parent)
        return;

    sib = SIBLING(n);

    /* case 2: n's sibling is red */
    if (IS_RED(sib))
    {
        n->parent->color = RED;
        sib->color = BLACK;

        if (IS_LEFT_CHILD(n))
            bst_rotate_left(t, n->parent);
        else
            bst_rotate_right(t, n->parent);

        sib = SIBLING(n);
    }

    /* case 3: parent sib and sib's children are black */
    if (n->parent->color == BLACK &&
        sib->color == BLACK &&
        IS_BLACK(sib->left) &&
        IS_BLACK(sib->right))
    {
        sib->color = RED;
        bst_remove_repair(t, n->parent);
        return;
    }

    /* case 4: parent is red, sib and sib's children are black */
    if (n->parent->color == RED &&
        sib->color == BLACK &&
        IS_BLACK(sib->left) &&
        IS_BLACK(sib->right))
    {
        sib->color = RED;
        n->parent->color = BLACK;
        return;
    }

    /* case 5: 
        a) n is left child, sib and sib->right child are black, sib->left is red
        b) n is right child, sib and sib->left child are black, sib->right is red
    */
    if (IS_LEFT_CHILD(n) &&
        sib->color == BLACK &&
        IS_RED(sib->left) &&
        IS_BLACK(sib->right))
    {
        sib->color = RED;
        sib->left->color = BLACK;
        bst_rotate_right(t, sib);
        sib = SIBLING(n);
    }
    else if (IS_RIGHT_CHILD(n) &&
        sib->color == BLACK &&
        IS_RED(sib->right) && 
        IS_BLACK(sib->left))
    {
        sib->color = RED;
        sib->right->color = BLACK;
        bst_rotate_left(t, sib);
        sib = SIBLING(n);
    }

    /* case 6: */ 
    sib->color = n->parent->color;
    n->parent->color = BLACK;
    if (IS_LEFT_CHILD(n))
    {
        sib->right->color = BLACK;
        bst_rotate_left(t, n->parent);
    }
    else
    {
        sib->left->color = BLACK;
        bst_rotate_right(t, n->parent);
    }
}