Пример #1
0
static struct rb_node *
rb_next_preorder_(struct rb_node *rbn, int *black_depth)
{
	if (rbn->c[0]) {
		if (!rb_is_red(rbn->c[0]))
			*black_depth++;
		return rbn->c[0];
	} else if (rbn->c[1]) {
		if (!rb_is_red(rbn->c[1]))
			*black_depth++;
		return rbn->c[1];
	} else {
		int l = *black_depth;
		/* go up to the next right child we missed */
		for (;;) {
			if (!rb_is_red(rbn))
				l--;
			struct rb_node *p = rb_parent(rbn);
			if (!p) {
				*black_depth = l;
				return NULL;
			}

			if (p->c[1]) {
				if (!rb_is_red(p->c[1]))
					*black_depth = l;
				return p->c[1];
			}
		}
	}
}
Пример #2
0
void rb_insert_color(struct rb_node *node, struct rb_root *root)
{
	struct rb_node *parent, *gparent;

	while((parent = rb_parent(node)) && rb_is_red(parent)) {

		gparent = rb_parent(parent);

		if(parent == gparent->rb_left) {
			{
				register struct rb_node *uncle = gparent->rb_right;
				if(uncle && rb_is_red(uncle)) {
					rb_set_black(uncle);
					rb_set_black(parent);
					rb_set_red(gparent);
					node = gparent;
					continue;
				}
			}

			if(parent->rb_right == node) {
				register struct rb_node *tmp;
				__rb_rotate_left(parent, root);
				tmp = parent;
				parent = node;
				node = tmp;
			}
			
			rb_set_black(parent);
			rb_set_red(gparent);
			__rb_rotate_right(gparent, root);
		} else {
			{
				register struct rb_node *uncle = gparent->rb_left;
				if(uncle && rb_is_red(uncle)) {
					rb_set_black(uncle);
					rb_set_black(parent);
					rb_set_red(gparent);
					node = gparent;
					continue;
				}
			}

			if(parent->rb_left == node) {
				register struct rb_node *tmp;
				__rb_rotate_right(parent, root);
				tmp = parent;
				parent = node;
				node = tmp;
			}
			
			rb_set_black(parent);
			rb_set_red(gparent);
			__rb_rotate_left(gparent, root);
		}

	}

	rb_set_black(root->rb_node);
}
Пример #3
0
size_t rb_check_subtree(NodeTy* node, NodeTy** list)
{
	size_t ret = 0;
	if (node)
	{
		if (rb_is_red(node))
		{
			if (*list == nullptr)
			{
				throw ::std::runtime_error("root is red");
			}
			if (rb_is_red(*list))
			{
				throw ::std::runtime_error("two red node");
			}
		}
		else
		{
			++ret;
		}
		*++list = node;
		const size_t left = rb_check_subtree<NodeTy>(node->rb_left, list);
		const size_t right = rb_check_subtree<NodeTy>(node->rb_right, list);
		if (left != right)
		{
			throw ::std::runtime_error("number of black nodes does not match");
		}
		ret += left;
		return ret;
	}
	return 0;
}
Пример #4
0
static noinline bool dump_tree_aux(struct rb_node *node, struct rb_node *parent,
				   int depth, char lr)
{
	struct afs_vnode *vnode;
	bool bad = false;

	if (!node)
		return false;

	if (node->rb_left)
		bad = dump_tree_aux(node->rb_left, node, depth + 2, '/');

	vnode = rb_entry(node, struct afs_vnode, cb_promise);
	_debug("%c %*.*s%c%p {%d}",
	       rb_is_red(node) ? 'R' : 'B',
	       depth, depth, "", lr,
	       vnode, vnode->cb_expires_at);
	if (rb_parent(node) != parent) {
;
		bad = true;
	}

	if (node->rb_right)
		bad |= dump_tree_aux(node->rb_right, node, depth + 2, '\\');

	return bad;
}
Пример #5
0
/*
 * 打印"红黑树"
 *
 * tree       -- 红黑树的节点
 * key        -- 节点的键值 
 * direction  --  0,表示该节点是根节点;
 *               -1,表示该节点是它的父结点的左孩子;
 *                1,表示该节点是它的父结点的右孩子。
 */
static void rbtree_print(RBTree tree, Type key, int direction)
{
    if(tree != NULL)
    {
        if(direction==0)    // tree是根节点
            printf("%2d(B) is root\n", tree->key);
        else                // tree是分支节点
            printf("%2d(%s) is %2d's %6s child\n", tree->key, rb_is_red(tree)?"R":"B", key, direction==1?"right" : "left");

        rbtree_print(tree->left, tree->key, -1);
        rbtree_print(tree->right,tree->key,  1);
    }
}
Пример #6
0
static void __rb_erase_color(LPRB_NODE node, LPRB_NODE parent, LPRB_ROOT root)
{
	LPRB_NODE other;

	while ((!node || rb_is_black(node)) && node != root->rb_node)
	{
		if (parent->rb_left == node)
		{
			other = parent->rb_right;
			if (rb_is_red(other))
			{
				rb_set_black(other);
				rb_set_red(parent);
				__rb_rotate_left(parent, root);
				other = parent->rb_right;
			}
			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
			    (!other->rb_right || rb_is_black(other->rb_right)))
			{
				rb_set_red(other);
				node = parent;
				parent = rb_parent(node);
			}
			else
			{
				if (!other->rb_right || rb_is_black(other->rb_right))
				{
					rb_set_black(other->rb_left);
					rb_set_red(other);
					__rb_rotate_right(other, root);
					other = parent->rb_right;
				}
				rb_set_color(other, rb_color(parent));
				rb_set_black(parent);
				rb_set_black(other->rb_right);
				__rb_rotate_left(parent, root);
				node = root->rb_node;
				break;
			}
		}
		else
		{
			other = parent->rb_left;
			if (rb_is_red(other))
			{
				rb_set_black(other);
				rb_set_red(parent);
				__rb_rotate_right(parent, root);
				other = parent->rb_left;
			}
			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
			    (!other->rb_right || rb_is_black(other->rb_right)))
			{
				rb_set_red(other);
				node = parent;
				parent = rb_parent(node);
			}
			else
			{
				if (!other->rb_left || rb_is_black(other->rb_left))
				{
					rb_set_black(other->rb_right);
					rb_set_red(other);
					__rb_rotate_left(other, root);
					other = parent->rb_left;
				}
				rb_set_color(other, rb_color(parent));
				rb_set_black(parent);
				rb_set_black(other->rb_left);
				__rb_rotate_right(parent, root);
				node = root->rb_node;
				break;
			}
		}
	}
	if (node)
		rb_set_black(node);
}
Пример #7
0
void rb_insert_color(LPRB_NODE node, LPRB_ROOT root)
{
	LPRB_NODE parent, gparent;

	while ((parent = rb_parent(node)) && rb_is_red(parent))
	{
		gparent = rb_parent(parent);

		if (parent == gparent->rb_left)
		{
			{
				register LPRB_NODE uncle = gparent->rb_right;
				if (uncle && rb_is_red(uncle))
				{
					rb_set_black(uncle);
					rb_set_black(parent);
					rb_set_red(gparent);
					node = gparent;
					continue;
				}
			}

			if (parent->rb_right == node)
			{
				register LPRB_NODE tmp;
				__rb_rotate_left(parent, root);
				tmp = parent;
				parent = node;
				node = tmp;
			}

			rb_set_black(parent);
			rb_set_red(gparent);
			__rb_rotate_right(gparent, root);
		} else {
			{
				register LPRB_NODE uncle = gparent->rb_left;
				if (uncle && rb_is_red(uncle))
				{
					rb_set_black(uncle);
					rb_set_black(parent);
					rb_set_red(gparent);
					node = gparent;
					continue;
				}
			}

			if (parent->rb_left == node)
			{
				register LPRB_NODE tmp;
				__rb_rotate_right(parent, root);
				tmp = parent;
				parent = node;
				node = tmp;
			}

			rb_set_black(parent);
			rb_set_red(gparent);
			__rb_rotate_left(gparent, root);
		}
	}

	rb_set_black(root->rb_node);
}
Пример #8
0
static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
			     struct rb_root *root)
{
	struct rb_node *other;

	while ((!node || rb_is_black(node)) && node != root->rb_node)
	{
		if (parent->rb_left == node)
		{
			other = parent->rb_right;
			if (rb_is_red(other))
			{
				rb_set_black(other);
				rb_set_red(parent);
				__rb_rotate_left(parent, root);
				other = parent->rb_right;
			}
			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
			    (!other->rb_right || rb_is_black(other->rb_right)))
			{
				rb_set_red(other);
				node = parent;
				parent = rb_parent(node);
			}
			else
			{
				if (!other->rb_right || rb_is_black(other->rb_right))
				{
					struct rb_node *o_left;
					if ((o_left = other->rb_left))
						rb_set_black(o_left);
					rb_set_red(other);
					__rb_rotate_right(other, root);
					other = parent->rb_right;
				}
				rb_set_color(other, rb_color(parent));
				rb_set_black(parent);
				if (other->rb_right)
					rb_set_black(other->rb_right);
				__rb_rotate_left(parent, root);
				node = root->rb_node;
				break;
			}
		}
		else
		{
			other = parent->rb_left;
			if (rb_is_red(other))
			{
				rb_set_black(other);
				rb_set_red(parent);
				__rb_rotate_right(parent, root);
				other = parent->rb_left;
			}
			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
			    (!other->rb_right || rb_is_black(other->rb_right)))
			{
				rb_set_red(other);
				node = parent;
				parent = rb_parent(node);
			}
			else
			{
				if (!other->rb_left || rb_is_black(other->rb_left))
				{
					register struct rb_node *o_right;
					if ((o_right = other->rb_right))
						rb_set_black(o_right);
					rb_set_red(other);
					__rb_rotate_left(other, root);
					other = parent->rb_left;
				}
				rb_set_color(other, rb_color(parent));
				rb_set_black(parent);
				if (other->rb_left)
					rb_set_black(other->rb_left);
				__rb_rotate_right(parent, root);
				node = root->rb_node;
				break;
			}
		}
	}
	if (node)
		rb_set_black(node);
}
Пример #9
0
void rb_insert_color(struct rb_node *node, struct rb_root *root)
{
	struct rb_node *parent, *gparent;
	
	struct mytype *mytype;
	
	int pr_flag = 1;
	
	mytype = container_of(node, struct mytype, node);

	while ((parent = rb_parent(node)) && rb_is_red(parent))
	{
		gparent = rb_parent(parent);

		if (parent == gparent->rb_left)
		{
			{
				register struct rb_node *uncle = gparent->rb_right;
				if (uncle && rb_is_red(uncle))
				{
					if (pr_flag)
					{
						pr_debug("insert value = %02d, 对应情况1。\n", mytype->keyvalue);
						pr_flag = 0;
					}					
					
					rb_set_black(uncle);
					rb_set_black(parent);
					rb_set_red(gparent);
					node = gparent;
					
					continue;
				}
			}

			if (parent->rb_right == node)
			{
				if (pr_flag)
				{
					pr_debug("insert value = %02d, 对应情况2。\n", mytype->keyvalue);
					pr_flag = 0;
				}				
				
				register struct rb_node *tmp;
				__rb_rotate_left(parent, root);
				tmp = parent;
				parent = node;
				node = tmp;
			}
			
			if (pr_flag)
			{
				pr_debug("insert value = %02d, 对应情况3。\n", mytype->keyvalue);
				pr_flag = 0;
			}		

			rb_set_black(parent);
			rb_set_red(gparent);
			__rb_rotate_right(gparent, root);
		} else {
			{
				register struct rb_node *uncle = gparent->rb_left;
				if (uncle && rb_is_red(uncle))
				{
					if (pr_flag)
					{
						pr_debug("insert value = %02d, 对应情况1(反)。\n", mytype->keyvalue);
						pr_flag = 0;
					}	
					
					rb_set_black(uncle);
					rb_set_black(parent);
					rb_set_red(gparent);
					node = gparent;
					continue;
				}
			}

			if (parent->rb_left == node)
			{
				if (pr_flag)
				{
					pr_debug("insert value = %02d, 对应情况2(反)。\n", mytype->keyvalue);
					pr_flag = 0;
				}	
				
				register struct rb_node *tmp;
				__rb_rotate_right(parent, root);
				tmp = parent;
				parent = node;
				node = tmp;
			}
			
			if (pr_flag)
			{
				pr_debug("insert value = %02d, 对应情况3(反)。\n", mytype->keyvalue);
				pr_flag = 0;
			}	

			rb_set_black(parent);
			rb_set_red(gparent);
			__rb_rotate_left(gparent, root);
		}
	}
	
	if (pr_flag)
		pr_debug("insert value = %02d, 对应情况X。\n", mytype->keyvalue);

	rb_set_black(root->rb_node);
}
Пример #10
0
static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
			     struct rb_root *root)
{
	struct rb_node *other;
	
	int pr_flag = 1;

	while ((!node || rb_is_black(node)) && node != root->rb_node)
	{
		if (parent->rb_left == node)
		{
			other = parent->rb_right;
			if (rb_is_red(other))
			{
				if (pr_flag)
				{
					pr_debug("对应情况1。\n");
					pr_flag = 0;
				}	
				
				rb_set_black(other);
				rb_set_red(parent);
				__rb_rotate_left(parent, root);
				other = parent->rb_right;
			}
			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
			    (!other->rb_right || rb_is_black(other->rb_right)))
			{				
				if (pr_flag)
				{
					pr_debug("对应情况2。\n");
					pr_flag = 0;
				}	
				
				rb_set_red(other);
				node = parent;
				parent = rb_parent(node);
			}
			else
			{
				if (!other->rb_right || rb_is_black(other->rb_right))
				{
					if (pr_flag)
					{
						pr_debug("对应情况3。\n");
						pr_flag = 0;
					}						
					
					rb_set_black(other->rb_left);
					rb_set_red(other);
					__rb_rotate_right(other, root);
					other = parent->rb_right;
				}
				
				if (pr_flag)
				{
					pr_debug("对应情况4。\n");
					pr_flag = 0;
				}
				
				rb_set_color(other, rb_color(parent));
				rb_set_black(parent);
				rb_set_black(other->rb_right);
				__rb_rotate_left(parent, root);
				node = root->rb_node;
				break;
			}
		}
		else
		{
			other = parent->rb_left;
			if (rb_is_red(other))
			{
				if (pr_flag)
				{
					pr_debug("对应情况1(反)。\n");
					pr_flag = 0;
				}	
				
				rb_set_black(other);
				rb_set_red(parent);
				__rb_rotate_right(parent, root);
				other = parent->rb_left;
			}
			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
			    (!other->rb_right || rb_is_black(other->rb_right)))
			{
				if (pr_flag)
				{
					pr_debug("对应情况2(反)。\n");
					pr_flag = 0;
				}	
				
				rb_set_red(other);
				node = parent;
				parent = rb_parent(node);
			}
			else
			{
				if (!other->rb_left || rb_is_black(other->rb_left))
				{
					if (pr_flag)
					{
						pr_debug("对应情况3(反)。\n");
						pr_flag = 0;
					}	
					
					
					rb_set_black(other->rb_right);
					rb_set_red(other);
					__rb_rotate_left(other, root);
					other = parent->rb_left;
				}
				
				if (pr_flag)
				{
					pr_debug("对应情况4(反)。\n");
					pr_flag = 0;
				}	
				
				rb_set_color(other, rb_color(parent));
				rb_set_black(parent);
				rb_set_black(other->rb_left);
				__rb_rotate_right(parent, root);
				node = root->rb_node;
				break;
			}
		}
	}
	
	if (pr_flag)
	{
		if (node && rb_is_red(node))	//红结点
		{
			pr_debug("对应情况S。\n");
		}
		else
		{
			pr_debug("对应情况?。\n");
		}
	}
	
	if (node) 		
		rb_set_black(node);
		

}
Пример #11
0
static void rbtree_remove(char *node, char **tree)
{
    char *parent = rb_get_parent(node);
    char *left = rbtree_get_left(node);
    char *right = rbtree_get_right(node);
    char *next;
    int color;

    if (!left)
        next = right;
    else if (!right)
        next = left;
    else
        next = rbtree_first(right);

    if (parent)
        rb_set_child(next, parent, rbtree_get_left(parent) == node);
    else
        *tree = next;

    if (left && right) {
        color = rb_get_color(next);
        rb_set_color(rb_get_color(node), next);

        rb_set_left(left, next);
        rb_set_parent(next, left);

        if (next != right) {
            parent = rb_get_parent(next);
            rb_set_parent(rb_get_parent(node), next);

            node = rbtree_get_right(next);
            rb_set_left(node, parent);

            rb_set_right(right, next);
            rb_set_parent(next, right);
        } else {
            rb_set_parent(parent, next);
            parent = next;
            node = rbtree_get_right(next);
        }
    } else {
        color = rb_get_color(node);
        node = next;
    }
    /*
     * 'node' is now the sole successor's child and 'parent' its
     * new parent (since the successor can have been moved).
     */
    if (node)
        rb_set_parent(parent, node);

    /*
     * The 'easy' cases.
     */
    if (color == RB_RED)
        return;
    if (node && rb_is_red(node)) {
        rb_set_color(RB_BLACK, node);
        return;
    }

    do {
        if (node == *tree)
            break;

        if (node == rbtree_get_left(parent)) {
            char *sibling = rbtree_get_right(parent);

            if (rb_is_red(sibling)) {
                rb_set_color(RB_BLACK, sibling);
                rb_set_color(RB_RED, parent);
                rb_rotate_left(parent, tree);
                sibling = rbtree_get_right(parent);
            }
            if ((!rbtree_get_left(sibling)  || rb_is_black(rbtree_get_left(sibling))) &&
                (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling)))) {
                rb_set_color(RB_RED, sibling);
                node = parent;
                parent = rb_get_parent(parent);
                continue;
            }
            if (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling))) {
                rb_set_color(RB_BLACK, rbtree_get_left(sibling));
                rb_set_color(RB_RED, sibling);
                rb_rotate_right(sibling, tree);
                sibling = rbtree_get_right(parent);
            }
            rb_set_color(rb_get_color(parent), sibling);
            rb_set_color(RB_BLACK, parent);
            rb_set_color(RB_BLACK, rbtree_get_right(sibling));
            rb_rotate_left(parent, tree);
            node = *tree;
            break;
        } else {
            char *sibling = rbtree_get_left(parent);

            if (rb_is_red(sibling)) {
                rb_set_color(RB_BLACK, sibling);
                rb_set_color(RB_RED, parent);
                rb_rotate_right(parent, tree);
                sibling = rbtree_get_left(parent);
            }
            if ((!rbtree_get_left(sibling)  || rb_is_black(rbtree_get_left(sibling))) &&
                (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling)))) {
                rb_set_color(RB_RED, sibling);
                node = parent;
                parent = rb_get_parent(parent);
                continue;
            }
            if (!rbtree_get_left(sibling) || rb_is_black(rbtree_get_left(sibling))) {
                rb_set_color(RB_BLACK, rbtree_get_right(sibling));
                rb_set_color(RB_RED, sibling);
                rb_rotate_left(sibling, tree);
                sibling = rbtree_get_left(parent);
            }
            rb_set_color(rb_get_color(parent), sibling);
            rb_set_color(RB_BLACK, parent);
            rb_set_color(RB_BLACK, rbtree_get_left(sibling));
            rb_rotate_right(parent, tree);
            node = *tree;
            break;
        }
    } while (rb_is_black(node));

    if (node)
        rb_set_color(RB_BLACK, node);
}
Пример #12
0
static char *rbtree_insert(char *node, char **tree)
{
    char *key, *parent;
    int is_left;

    key = rb_do_lookup(node, *tree, &parent, &is_left);
    if (key)
        return key;

    rb_set_left(NULL, node);
    rb_set_right(NULL, node);
    rb_set_color(RB_RED, node);
    rb_set_parent(parent, node);

    if (parent) {
        rb_set_child(node, parent, is_left);
    } else {
        *tree = node;
    }

    /*
     * Fixup the modified tree by recoloring nodes and performing
     * rotations (2 at most) hence the red-black tree properties are
     * preserved.
     */
    while ((parent = rb_get_parent(node)) && rb_is_red(parent)) {
        char *grandpa = rb_get_parent(parent);

        if (parent == rbtree_get_left(grandpa)) {
            char *uncle = rbtree_get_right(grandpa);

            if (uncle && rb_is_red(uncle)) {
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_BLACK, uncle);
                rb_set_color(RB_RED, grandpa);
                node = grandpa;
            } else {
                if (node == rbtree_get_right(parent)) {
                    rb_rotate_left(parent, tree);
                    node = parent;
                    parent = rb_get_parent(node);
                }
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_RED, grandpa);
                rb_rotate_right(grandpa, tree);
            }
        } else {
            char *uncle = rbtree_get_left(grandpa);

            if (uncle && rb_is_red(uncle)) {
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_BLACK, uncle);
                rb_set_color(RB_RED, grandpa);
                node = grandpa;
            } else {
                if (node == rbtree_get_left(parent)) {
                    rb_rotate_right(parent, tree);
                    node = parent;
                    parent = rb_get_parent(node);
                }
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_RED, grandpa);
                rb_rotate_left(grandpa, tree);
            }
        }
    }
    rb_set_color(RB_BLACK, *tree);
    return NULL;
}
Пример #13
0
void rb_insert_rebalance(struct rb_node* node, struct rb_root* root)
{
    struct rb_node *parent, *gparent, *uncle;

    while ((parent = rb_parent(node)) && rb_is_red(parent)) {

        gparent = rb_parent(parent);

        if (parent == gparent->left) {
            uncle = gparent->right;
            if (uncle && rb_is_red(uncle)) {
                rb_set_black(uncle);
                rb_set_black(parent);
                rb_set_red(gparent);
                node = gparent;

                continue;
            }

            if (node == parent->right) {
                register struct rb_node* tmp;

                rb_rotate_left(parent, root);
                tmp = node;
                node = parent;
                parent = tmp;
            }

            rb_rotate_right(gparent, root);
            rb_set_black(parent);
            rb_set_red(gparent);

            continue;
        }

        uncle = gparent->left;
        if (uncle && rb_is_red(uncle)) {
            rb_set_black(parent);
            rb_set_black(uncle);
            rb_set_red(gparent);
            node = gparent;

            continue;
        }

        if (node == parent->left) {
            register struct rb_node* tmp;

            rb_rotate_right(parent, root);
            tmp = node;
            node = parent;
            parent = tmp;
        }

        rb_rotate_left(gparent, root);
        rb_set_red(gparent);
        rb_set_black(parent);
    }

    rb_set_black(root->node);
}
Пример #14
0
static inline void rb_delete_rebalance(struct rb_node* node,
                                       struct rb_node* parent,
                                       struct rb_root* root)
{
    struct rb_node* sibling;

    while ((!node || rb_is_black(node)) && (node != root->node)) {
        if (node == parent->left) {
            sibling = parent->right;

            if (rb_is_red(sibling)) {
                rb_rotate_left(parent, root);
                rb_set_red(parent);
                rb_set_black(sibling);
                sibling = parent->right;
            }

            if ((!sibling->left || rb_is_black(sibling->left)) &&
                (!sibling->right || rb_is_black(sibling->right))) {
                rb_set_red(sibling);
                node = parent;
                /* if (node) */ parent = rb_parent(node);
            } else {
                if (!sibling->right || rb_is_black(sibling->right)) {
                    rb_set_black(sibling->left);
                    rb_set_red(sibling);
                    rb_rotate_right(sibling, root);
                    sibling = parent->right;
                }

                rb_set_color(sibling, rb_color(parent));
                rb_set_black(parent);
                rb_set_black(sibling->right);
                rb_rotate_left(parent, root);
                node = root->node;

                break;
            }
        } else {
            sibling = parent->left;

            if (rb_is_red(sibling)) {
                rb_rotate_right(parent, root);
                rb_set_red(parent);
                rb_set_black(sibling);
                sibling = parent->left;
            }

            if ((!sibling->left || rb_is_black(sibling->left)) &&
                (!sibling->right || rb_is_black(sibling->right))) {
                rb_set_red(sibling);
                node = parent;
                /* if (node) */ parent = rb_parent(node);
            } else {
                if (!sibling->left || rb_is_black(sibling->left)) {
                    rb_set_black(sibling->right);
                    rb_set_red(sibling);
                    rb_rotate_left(sibling, root);
                    sibling = parent->left;
                }

                rb_set_color(sibling, rb_color(parent));
                rb_set_black(parent);
                rb_set_black(sibling->left);
                rb_rotate_right(parent, root);
                node = root->node;

                break;
            }
        }
    }

    if (node)
        rb_set_black(node);
}
Пример #15
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);
}
Пример #16
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);
}