C++ 红黑树增加、删除等操作

#include <iostream>
#include <iomanip>
using namespace std;

class RBNode{
    public:
        int color;    //0为红色,1为黑色
        int key;           
        RBNode *left;    
        RBNode *right;    
        RBNode *parent; 
        RBNode(int value, int c, RBNode *p, RBNode *l, RBNode *r):
            key(value),color(c),parent(),left(l),right(r) {}
};
class RBTree {
    private:
        RBNode *mRoot;   
    public:
		RBTree(){mRoot=NULL;}
        void insert(int key);	
        void Delete(int key);
        void output();
    private:
        RBNode* find(RBNode* x, int key) ;
        void left(RBNode* &root, RBNode* x);
        void right(RBNode* &root, RBNode* y);
        void insert(RBNode* &root, RBNode* node);
        void insertFixUp(RBNode* &root, RBNode* node);
        void Delete(RBNode* &root, RBNode *node);
        void deleteFixUp(RBNode* &root, RBNode *node, RBNode *parent);
        void output(RBNode* tree, int key, int x);
};
RBNode* RBTree::find(RBNode* x, int key) 
{
    if (x==NULL || x->key==key)
        return x;

    if (key < x->key)
        return find(x->left, key);
    else
        return find(x->right, key);
}
void RBTree::left(RBNode* &root, RBNode* x)
{
    RBNode *y = x->right;
    x->right = y->left;
    if (y->left != NULL)
        y->left->parent = x;
    y->parent = x->parent;

    if (x->parent == NULL)
    {
        root = y;            
    }
    else
    {
        if (x->parent->left == x)
            x->parent->left = y;   
        else
            x->parent->right = y;    
    }
    y->left = x;
    x->parent = y;
}
void RBTree::right(RBNode* &root, RBNode* y)
{
    RBNode *x = y->left;
    y->left = x->right;
    if (x->right != NULL)
        x->right->parent = y;
    x->parent = y->parent;
    if (y->parent == NULL) 
    {
        root = x;          
    }
    else
    {
        if (y == y->parent->right)
            y->parent->right = x;    
        else
            y->parent->left = x;    
    }
    x->right = y;
    y->parent = x;
}
void RBTree::insertFixUp(RBNode* &root, RBNode* node)
{
    RBNode *parent, *gparent;
	while ((parent =node->parent) && (parent->color==0))
    {
		gparent=parent->parent;
        if (parent == gparent->left)
        {
            
                RBNode *uncle = gparent->right;
				if (uncle && (uncle->color==0))
                {
					uncle->color=1;
					parent->color=1;
					gparent->color=0;
                    node = gparent;
                    continue;
                }
            
            if (parent->right == node)
            {
                RBNode *tmp;
                left(root, parent);
                tmp = parent;
                parent = node;
                node = tmp;
            }
			parent->color=1;
			gparent->color=0;
            right(root, gparent);
        } 
        else
        {
            
                RBNode *uncle = gparent->left;
				if (uncle && (uncle->color==0))
                {
					uncle->color=1;
					parent->color=1;
					gparent->color=1;
                    node = gparent;
                    continue;
                }
            
            if (parent->left == node)
            {
                RBNode *tmp;
                right(root, parent);
                tmp = parent;
                parent = node;
                node = tmp;
            }
			parent->color=1;
			gparent->color=0;
            left(root, gparent);
        }
    }
	root->color=1;
}
void RBTree::insert(RBNode* &root, RBNode *node)
{
    RBNode *y = NULL;
    RBNode *x = root;
    while (x != NULL)
    {
        y = x;
        if (node->key < x->key)
            x = x->left;
        else
            x = x->right;
    }
    node->parent = y;
    if (y!=NULL)
    {
        if (node->key < y->key)
            y->left = node;
        else
            y->right = node;
    }
    else
        root = node;
    node->color = 0;
    insertFixUp(root, node);
}
void RBTree::insert(int key)
{
    RBNode *z=NULL;
    if ((z=new RBNode(key,1,NULL,NULL,NULL)) == NULL)
        return ;
    insert(mRoot, z);
}
void RBTree::deleteFixUp(RBNode* &root, RBNode *node, RBNode *parent)
{
    RBNode *y;
	while ((!node || (node->color==1)) && node != root)
    {
        if (parent->left == node)
        {
            y = parent->right;
			if ((y->color==0))
            {
				y->color=1;
				parent->color=0;
                left(root, parent);
                y = parent->right;
            }
			if ((!y->left || (y->left->color==1)) &&
				(!y->right || (y->right->color==1)))
            {
				y->color=0;
                node = parent;
				parent=node->parent;
            }
            else
            {
				if (!y->right || (y->right->color==1))
                {
					y->left->color=1;
					y->color=0;
					right(root, y);
                    y = parent->right;
                }
				y->color=parent->color;
				parent->color=1;
				y->right->color=1;
                left(root, parent);
                node = root;
                break;
            }
        }
        else
        {
            y = parent->left;
			if ((y->color==0))
            {
				y->color=1;
				parent->color=0;
                right(root, parent);
                y = parent->left;
            }
			if ((!y->left || (y->left->color==1)) &&
				(!y->right || (y->right->color==1)))
            {
				y->color=0;
                node = parent;
				parent=node->parent;
            }
            else
            {
				if (!y->left || (y->left->color==1))
                {
					y->right->color=1;
					y->color=0;
                    left(root, y);
                    y = parent->left;
                }
				y->color=parent->color;
				parent->color=1;
				y->left->color=1;
                right(root, parent);
                node = root;
                break;
            }
        }
    }
    if (node)
		node->color=1;
}
void RBTree::Delete(RBNode* &root, RBNode *node)
{
    RBNode *child, *parent;
    int color;
    if ( (node->left!=NULL) && (node->right!=NULL) ) 
    {
        RBNode *y = node;
        y = y->right;
        while (y->left != NULL)
            y = y->left;
		if (node->parent)
        {
			if (node->parent->left == node)        
			   node->parent->left = y;
            else
			   node->parent->right = y;
        } 
        else 
            root = y;
        child = y->right;
		parent = y->parent;
		color = y->color;
        if (parent == node)
        {
            parent = y;
        } 
        else
        {
            if (child)
				child->parent=parent;
            parent->left = child;
            y->right = node->right;
			node->right->parent=y;
        }

        y->parent = node->parent;
        y->color = node->color;
        y->left = node->left;
        node->left->parent = y;

        if (color == 1)
            deleteFixUp(root, child, parent);

        delete node;
        return ;
    }

    if (node->left !=NULL)
        child = node->left;
    else 
        child = node->right;

    parent = node->parent;
    color = node->color;

    if (child)
        child->parent = parent;
    if (parent)
    {
        if (parent->left == node)
            parent->left = child;
        else
            parent->right = child;
    }
    else
        root = child;

    if (color == 1)
        deleteFixUp(root, child, parent);
    delete node;
}
void RBTree::Delete(int key)
{
    RBNode *node; 
    if ((node = find(mRoot, key)) != NULL)
        Delete(mRoot, node);
}
void RBTree::output(RBNode* tree, int key, int x)
{
    if(tree != NULL)
    {
        if(x==0)    
            cout << setw(2) << tree->key << "(B) is root" << endl;
        else                
            cout << setw(2) << tree->key <<  ((tree->color==0)?"(R)":"(B)") << " is " << setw(2) << key << "'s "  << setw(12) << (x==1?"right child" : "left child") << endl;

        output(tree->left, tree->key, -1);
        output(tree->right,tree->key,  1);
    }
}
void RBTree::output()
{
    if (mRoot != NULL)
        output(mRoot, mRoot->key, 0);
}
int main()
{
	int N,t;
	int a[20];
	 RBTree* tree;
	cout<<"请输入要插入的值的个数:"<<endl;
	cin>>N;
	tree=new RBTree();
	for(int i=0;i<N;i++)
	{
		cout<<"请输入第"<<i<<"个值:"<<endl;
		cin>>a[i];	
		tree->insert(a[i]);	 
	}
	tree->output();
	cout<<"是否需要删除节点?0(否)/1(是)"<<endl;
	int c;
	cin>>c;
	if(c)
	{
		cout<<"请输入需要删除的节点数:"<<endl;
		cin>>c;
		while(c>N||c<1)
		{
			cout<<"请输入1~N之间的数!!!"<<endl;
			cin>>c;
		}
		for(int i=0;i<c;i++)
		{
			cout<<"请输入第"<<i<<"个值:"<<endl;
			cin>>a[i];
			tree->Delete(a[i]); 
		}
		tree->output();
	}
	system("pause");
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值