Пример #1
0
void rb_insert(rbtree* tree, int data) {
    rbnode* pn = rb_search(tree, data);
    rbnode* nn = create_rbnode(data);
    if (!pn) {
        tree->root = nn;
        nn->color = BLACK;
        return;
    }
    else if (data == pn->data) {
        return;
    }
    else if (data < pn->data) {
        pn->left = nn;
        nn->parent = pn;
    }
    else if (data > pn->data) {
        pn->right = nn;
        nn->parent = pn;
    }
    while (pn && pn->color == RED) {
        if (IS_LEFT(pn)) {
            rbnode* uncle = pn->parent->right;
            if (uncle && uncle->color == RED) {
                pn->color = uncle->color = BLACK;
                pn->parent->color = RED;
                nn = pn->parent;
                pn = nn->parent;
                continue;
            }
            if (IS_RIGHT(nn)) {
                LEFT_ROTATE(tree, pn);
                SWAP(nn, pn, rbnode*);
            }
            RIGHT_ROTATE(tree, pn->parent);
            pn->color = BLACK;
            pn->right->color = RED;
            break;
        }
        else {
            rbnode* uncle = pn->parent->left;
            if (uncle && uncle->color == RED) {
                pn->color = uncle->color = BLACK;
                pn->parent->color = RED;
                nn = pn->parent;
                pn = nn->parent;
                continue;
            }
            if (IS_LEFT(nn)) {
                RIGHT_ROTATE(tree, pn);
                SWAP(nn, pn, rbnode*);
            }
            LEFT_ROTATE(tree, pn->parent);
            pn->color = BLACK;
            pn->left->color = RED;
            break;
        }
    }
    // nn is root
    if (!pn) nn->color = BLACK;
}
Пример #2
0
void rb_insert_fixup(Node* &T, Node *n)
{
	// 如果n的父亲是红色,则需要调整
	// 如果n的父亲是黑色,则不需要调整,因为n本身是红色
	while(IS_RED(PARENT(n))) {
		// 根据n的叔叔节点的颜色,来决定调整方案
		Node *p = IS_LEFT(PARENT(n))? RIGHT(PARENT(PARENT(n))): LEFT(PARENT(PARENT(n)));

		// 如果叔叔是红色,那很简单,把爷爷的黑色转移给父亲和叔叔,爷爷刷成红色
		// 这样,即满足了性质4,也没有破坏性质5及其他性质
		// 但是,爷爷可能破坏了红黑性质4,则从爷爷开始继续调整(向上递归了两层)
		if (IS_RED(p)) {
			// 父亲刷成黑色
			SET_BLACK(PARENT(n));
			// 叔叔刷成黑色
			SET_BLACK(p);
			// 爷爷刷成红色
			SET_RED(PARENT(PARENT(n)));

			// 从爷爷开始继续调整
			n = PARENT(PARENT(n));
			continue;
		} 

		// 如果叔叔是黑色,就复杂一点,引入旋转操作
		// 如果n是左孩子,那么需要一次右旋+颜色调整即可
		// 如果n是右孩子,则通过一次左旋调整成左孩子,然后按上面情况处理
		if (IS_LEFT(PARENT(n))) { 
			// 如果n是右孩子,通过右旋调整成左孩子
			if (IS_RIGHT(n)) {
				n = PARENT(n);
				left_rotate(T, n);
			}

			// 现在n是左孩子了
			SET_BLACK(PARENT(n));
			SET_RED(PARENT(PARENT(n)));
			right_rotate(T, PARENT(PARENT(n)));
		} else {
			if (IS_LEFT(n)) {
				n = PARENT(n);
				right_rotate(T,n);
			}
			SET_BLACK(PARENT(n));
			SET_RED(PARENT(PARENT(n)));
			left_rotate(T,PARENT(PARENT(n)));
		}
	}
	
	// 如果n是根节点,则把根设置为黑色
	if (NIL == PARENT(n))
		SET_BLACK(n);
}
Пример #3
0
Node* tree_successor(const Node *n)
{
	Node *p = const_cast<Node*>(n);
	if (NIL == p)
		return p;

	if (NIL != RIGHT(p))
		return tree_min(RIGHT(p));
	
	while (IS_RIGHT(p) && (p = PARENT(p)));	
	return PARENT(p);
}
Пример #4
0
int os_rank(const Node *T, const Node *n)
{
	int r = SIZE(LEFT(n)) + 1;
	Node *p = const_cast<Node*>(n);
	while (p != T) {
		if (IS_RIGHT(p)) {
			r += SIZE(LEFT(PARENT(p))) +1;
		}
		p = PARENT(p);
	}

	return r;
}
Пример #5
0
static void RIGHT_ROTATE(rbtree* tree, rbnode* n)
{
    int is_left = IS_LEFT(n);
    int is_right = IS_RIGHT(n);
    rbnode* l = n->left;
    l->parent = n->parent;
    if (is_left) l->parent->left = l;
    else if (is_right) l->parent->right = l;
    else tree->root = l;
    n->left = l->right;
    if (n->left) n->left->parent = n;
    l->right = n;
    n->parent = l;
}
Пример #6
0
static void LEFT_ROTATE(rbtree* tree, rbnode* n)
{
    int is_left = IS_LEFT(n);
    int is_right = IS_RIGHT(n);
    rbnode* r = n->right;
    r->parent = n->parent;
    if (is_left) r->parent->left = r;
    else if (is_right) r->parent->right = r;
    else tree->root = r;
    n->right = r->left;
    if (n->right) n->right->parent = n;
    r->left = n;
    n->parent = r;
}
Пример #7
0
void inorder_tree_walk(const Node *T)
{
	if (NIL == T)
		return;

	// 按照两套规则处理:“未经过的节点”和“已经过的节点”
	Node *p = const_cast<Node*>(T);
	while (NIL != p) {
		// ============未经过的节点=============
		// 左孩子不为空, 则向下遍历左孩子
		if (NIL != LEFT(p)) {
			p = LEFT(p);
			continue;
		}
		// 左孩子为空,则访问本节点
		printf("%d(%d), ", KEY(p), SIZE(p));

		// 右孩子不为空,则访问右子树
		if (NIL != RIGHT(p)) {
			p = RIGHT(p);
			continue;
		}

		// ============已经过的节点=============
		// 右孩子为空,则开始向上处理父亲
		while (true) {
			if (IS_RIGHT(p)) {
				// 如果本节点是父亲的右孩子,则继续向上处理父亲
				p = PARENT(p);
			} else {
				// 本节点是父亲的左孩子,则访问父亲
				p = PARENT(p);
				printf("%d(%d), ", KEY(p), SIZE(p));

				// 如果右孩子不为空,则访问右子树(“未经过的节点”)
				if (NIL != RIGHT(p)) {
					p = RIGHT(p);
					break;
				}
				// 右孩子为空,则继续向上处理父亲
			}

			// 如果父亲是根,则意味着访问结束
			if (IS_ROOT(p))
				return;
		}
	}
}
Пример #8
0
void rb_delete(rbtree* tree, int data) {
    int color = RED;
    rbnode* dn = tree->root;
    rbnode* x = 0;
    rbnode* y = 0; //parent of deleted node
    rbnode* s = 0; //sibling
    rbnode* p = 0; //parent
    rbnode* ln =0; //left nephew
    rbnode* rn = 0; //right nephew
    int delcolor = 0;

    while (dn) {
        if (dn->data == data) break;
        else if (data < dn->data) dn = dn->left;
        else dn = dn->right;
    }
    if (!dn) return;

    delcolor = dn->color;
    y = dn->parent;
    if (!dn->left && !dn->right) {
        REPLACE(tree, dn, ((rbnode*)0));
        x = 0;
    }
    else if (!dn->left) {
        REPLACE(tree, dn, dn->right);
        x = dn->right;
    }
    else if (!dn->right) {
        REPLACE(tree, dn, dn->left);
        x = dn->left;
    }
    else {
        rbnode* rl = dn->right;
        while (rl->left) rl = rl->left;
        x = rl->right;
        y = rl == dn->right ? rl : rl->parent;
        delcolor = rl->color;
        REPLACE(tree, rl, rl->right);
        REPLACE(tree, dn, rl);
        rl->left = dn->left;
        rl->right = dn->right;
        rl->color = dn->color;
    }
    if (delcolor == RED) {
        destory_rbnode(dn);
        return;
    }
    while (IS_BLACK(x) && x != tree->root) {
        p = x ? x->parent : y;
        if ((!x && !y->left) || IS_LEFT(x)) {
            s = p->right;//s != 0,because x is black, the path to from s to null must has at least a black node

            if (s->color == RED) {
                LEFT_ROTATE(tree,p);
                p->color = RED;
                s->color = BLACK;
                continue;
            }
            else if (IS_BLACK(s->left) && IS_BLACK(s->right)) {
                s->color = RED;
                x = p;
                continue; 
            }
            ln = s->left;
            rn = s->right;

            if (IS_BLACK(rn)) {
                RIGHT_ROTATE(tree,s);
                s->color = RED;
                ln->color = BLACK;
                continue;
            }
            else {
                LEFT_ROTATE(tree,p);
                s->color = p->color;
                p->color = BLACK;
                x = rn;
                break;
            }
        }
        else if ((!x && !y->right) || IS_RIGHT(x)) {
            s = p->left;//s != 0,because x is black, the path to from s to null must has at least a black node

            if (s->color == RED) {
                RIGHT_ROTATE(tree,p);
                p->color = RED;
                s->color = BLACK;
                continue;
            }
            else if (IS_BLACK(s->left) && IS_BLACK(s->left)) {
                s->color = RED;
                x = p;
                continue; 
            }
            ln = s->left;
            rn = s->left;

            if (IS_BLACK(ln)) {
                LEFT_ROTATE(tree,s);
                s->color = RED;
                rn->color = BLACK;
                continue;
            }
            else {
                RIGHT_ROTATE(tree,p);
                s->color = p->color;
                p->color = BLACK;
                x = ln;
                break;
            }
        }
    }
    if (x) x->color = BLACK;
    destory_rbnode(dn);
    return;
}