示例#1
0
/************************************************************************
Rebalance the right sub-tree after deletion.
@return	node to rebalance if more rebalancing required else NULL */
static
ib_rbt_node_t*
rbt_balance_right(
/*==============*/
	const ib_rbt_node_t*	nil,		/*!< in: rb tree nil node */
	ib_rbt_node_t*		parent,		/*!< in: parent node */
	ib_rbt_node_t*		sibling)	/*!< in: sibling node */
{
	ib_rbt_node_t*		node = NULL;

	ut_a(sibling != nil);

	/* Case 3. */
	if (sibling->color == IB_RBT_RED) {

		parent->color = IB_RBT_RED;
		sibling->color = IB_RBT_BLACK;

		rbt_rotate_left(nil, parent);

		sibling = parent->right;

		ut_a(sibling != nil);
	}

	/* Since this will violate case 3 because of the change above. */
	if (sibling->left->color == IB_RBT_BLACK
	    && sibling->right->color == IB_RBT_BLACK) {

		node = parent; /* Parent needs to be rebalanced too. */
		sibling->color = IB_RBT_RED;

	} else {
		if (sibling->right->color == IB_RBT_BLACK) {

			ut_a(sibling->left->color == IB_RBT_RED);

			sibling->color = IB_RBT_RED;
			sibling->left->color = IB_RBT_BLACK;

			rbt_rotate_right(nil, sibling);

			sibling = parent->right;
			ut_a(sibling != nil);
		}

		sibling->color = parent->color;
		sibling->right->color = IB_RBT_BLACK;

		parent->color = IB_RBT_BLACK;

		rbt_rotate_left(nil, parent);
	}

	return(node);
}
示例#2
0
文件: rbbst.c 项目: aditya-os/my_dsa
struct rbnode * rbt_insert_node(struct rbnode *r,int key,void *val,int szval)
{
	if(r==NULL)
	{
		struct rbnode *item;
		item=malloc(sizeof(struct rbnode));
		if(!item)
			return NULL;
		rbt_node_init(item);
		rbt_node_fill(item,key,val,szval);
		return item;		
	}
	if(key < r->key)
	{
		r->lchild=rbt_insert_node(r->lchild,key,val,szval);
	}
	else if (key > r->key)
	{
		r->rchild=rbt_insert_node(r->rchild,key,val,szval);
	}
	else
	{
		r->dsz=szval;
	}
	
	if(rbt_isred(r->rchild) && !rbt_isred(r->lchild))
	{
		r=rbt_rotate_left(r);
	}
	if(rbt_isred(r->lchild) && rbt_isred(r->lchild->lchild))
	{	
		r=rbt_rotate_right(r);
	}
	if(rbt_isred(r->lchild) && rbt_isred(r->rchild))
	{
		rbt_flipcolor(r);
	}

	return r;
}
示例#3
0
/************************************************************************
Balance a tree after inserting a node. */
static
void
rbt_balance_tree(
/*=============*/
	const ib_rbt_t*	tree,			/*!< in: tree to balance */
	ib_rbt_node_t*	node)			/*!< in: node that was inserted */
{
	const ib_rbt_node_t*	nil = tree->nil;
	ib_rbt_node_t*		parent = node->parent;

	/* Restore the red-black property. */
	node->color = IB_RBT_RED;

	while (node != ROOT(tree) && parent->color == IB_RBT_RED) {
		ib_rbt_node_t*	grand_parent = parent->parent;

		if (parent == grand_parent->left) {
			ib_rbt_node_t*	uncle = grand_parent->right;

			if (uncle->color == IB_RBT_RED) {

				/* Case 1 - change the colors. */
				uncle->color = IB_RBT_BLACK;
				parent->color = IB_RBT_BLACK;
				grand_parent->color = IB_RBT_RED;

				/* Move node up the tree. */
				node = grand_parent;

			} else {

				if (node == parent->right) {
					/* Right is a black node and node is
					to the right, case 2 - move node
					up and rotate. */
					node = parent;
					rbt_rotate_left(nil, node);
				}

				grand_parent = node->parent->parent;

				/* Case 3. */
				node->parent->color = IB_RBT_BLACK;
				grand_parent->color = IB_RBT_RED;

				rbt_rotate_right(nil, grand_parent);
			}

		} else {
			ib_rbt_node_t*	uncle = grand_parent->left;

			if (uncle->color == IB_RBT_RED) {

				/* Case 1 - change the colors. */
				uncle->color = IB_RBT_BLACK;
				parent->color = IB_RBT_BLACK;
				grand_parent->color = IB_RBT_RED;

				/* Move node up the tree. */
				node = grand_parent;

			} else {

				if (node == parent->left) {
					/* Left is a black node and node is to
					the right, case 2 - move node up and
					rotate. */
					node = parent;
					rbt_rotate_right(nil, node);
				}

				grand_parent = node->parent->parent;

				/* Case 3. */
				node->parent->color = IB_RBT_BLACK;
				grand_parent->color = IB_RBT_RED;

				rbt_rotate_left(nil, grand_parent);
			}
		}

		parent = node->parent;
	}

	/* Color the root black. */
	ROOT(tree)->color = IB_RBT_BLACK;
}
示例#4
0
文件: rbtree.c 项目: cloud-hot/libhl
void
rbt_paint_onremove(rbt_t *rbt, rbt_node_t *node)
{
    if (!node)
        return;

    // delete case 1
    if (node->parent != NULL) {
        // delete case 2
        rbt_node_t *sibling = rbt_sibling(node);
        if (IS_RED(sibling)) {
            PAINT_RED(node->parent);
            PAINT_BLACK(sibling);
            if (node == node->parent->left) {
                rbt_rotate_left(rbt, node->parent);
            } else {
                rbt_rotate_right(rbt, node->parent);
            }
        }

        // delete case 3
        if (IS_BLACK(node->parent) &&
            sibling &&
            IS_BLACK(sibling) &&
            IS_BLACK(sibling->left) &&
            IS_BLACK(sibling->right))
        {
            PAINT_RED(sibling);
            rbt_paint_onremove(rbt, node->parent);
        } else {
            // delete case 4
            if (IS_RED(node->parent) &&
                sibling &&
                IS_BLACK(sibling) &&
                IS_BLACK(sibling->left) &&
                IS_BLACK(sibling->right))
            {
                PAINT_RED(sibling);
                PAINT_BLACK(node->parent);
            } else {
                // delete case 5
                if (IS_BLACK(sibling)) {
                    if (node == node->parent->left &&
                        sibling &&
                        IS_BLACK(sibling->right) &&
                        IS_RED(sibling->left))
                    {
                        PAINT_RED(sibling);
                        PAINT_BLACK(sibling->left);
                        rbt_rotate_right(rbt, sibling);
                    } else if (node == node->parent->right &&
                               sibling &&
                               IS_BLACK(sibling->left) &&
                               IS_RED(sibling->right))
                    {
                        PAINT_RED(sibling);
                        PAINT_BLACK(sibling->right);
                        rbt_rotate_left(rbt, sibling);

                    }
                }
                // delete case 6
                if (sibling)
                    sibling->color = node->parent->color;
                PAINT_BLACK(node->parent);
                if (node == node->parent->left) {
                    if (sibling)
                        PAINT_BLACK(sibling->right);
                    rbt_rotate_left(rbt, node->parent);
                } else {
                    if (sibling)
                        PAINT_BLACK(sibling->left);
                    rbt_rotate_right(rbt, node->parent);
                }
            }
        }
    }
}
示例#5
0
文件: rbtree.c 项目: cloud-hot/libhl
int
rbt_add(rbt_t *rbt, void *k, size_t klen, void *v)
{
    int rc = 0;
    rbt_node_t *node = calloc(1, sizeof(rbt_node_t));
    node->key = malloc(klen);
    memcpy(node->key, k, klen);
    node->klen = klen;
    node->value = v;
    if (!rbt->root) {
        PAINT_BLACK(node);
        rbt->root = node;
    } else {
        rc = _rbt_add_internal(rbt, rbt->root, node);

        if (IS_BLACK(node)) {
            // if the node just added is now black it means
            // it was already existing and this was only a value update
            if (!node->parent) {
                // we need to check also if the root pointer
                // should be updated as well
                rbt->root = node;
            }
            return 1;
        }
        
        if (!node->parent) {
            // case 1
            PAINT_BLACK(node);
            rbt->root = node;
        } else if (IS_BLACK(node->parent)) {
            // case 2
            return rc;
        } else {
            // case 3
            rbt_node_t *uncle = rbt_uncle(node);
            rbt_node_t *grandparent = rbt_grandparent(node);

            if (IS_RED(uncle)) {
                PAINT_BLACK(node->parent);
                PAINT_BLACK(uncle);
                if (grandparent) {
                    PAINT_RED(grandparent);
                    rbt_add(rbt, grandparent->key, grandparent->klen, grandparent->value);
                }
            } else if (grandparent) {
                // case 4
                if (node == node->parent->right && node->parent == grandparent->left) {
                    rbt_rotate_left(rbt, node->parent);
                    node = node->left;
                } else if (node == node->parent->left && node->parent == grandparent->right) {
                    rbt_rotate_right(rbt, node->parent);
                    node = node->right;
                }
                // case 5
                grandparent = rbt_grandparent(node);
                if (node->parent) {
                    PAINT_BLACK(node->parent);
                    PAINT_RED(grandparent);
                    if (node == node->parent->left)
                        rbt_rotate_right(rbt, grandparent);
                    else
                        rbt_rotate_left(rbt, grandparent);
                } else {
                    fprintf(stderr, "Corrupted tree\n");
                    return -1;
                }
            }
        }
    }
    return rc;
}