C++实现红黑树与验证

#include<iostream>  
#include<stack>  
#include<vector>
using namespace std;  
const bool black = 0;  
const bool red = 1;  
struct RBNode  
{  
    int key;  
    bool color;  
    RBNode *llink, *rlink, *parent;  
};  
class RBTree  
{  
public:  
    RBTree();  
    ~RBTree();  
    int insertNode(int key);          //插入元素接口  
    int deleteNode(int key);          //删除元素接口  
    void nPreOrder();                 //先序遍历非递归  
    void nInOrder();                  //中序遍历非递归  
    void nPostOrder();                //后序遍历非递归  
    bool isRBTree();                  //验证是否是红黑树
private:  
    void destroy(RBNode **proot);     //销毁树,析构函数用到  
    RBNode *createNode(int key);      //生成红黑树结点  
    void insertFixup(RBNode *pnode);  //插入元素后调整  
    RBNode *searchNode(int key);      //找指定元素的结点,删除元素函数用到  
    void transplant(RBNode *v0, RBNode *v1); //删除指定结点,删除元素函数用到  
    RBNode *minNode(RBNode *x);             //找到树中最小的元素,删除元素函数用到  
    void deleteFixup(RBNode *delNode);      //删除元素后调整  
    RBNode *rotate_right(RBNode *a);        //右旋  
    RBNode *rotate_left(RBNode *a);         //左旋  
    RBTree(const RBTree &obj);  
    RBTree &operator=(const RBTree &obj);  
    RBNode *root;  
    RBNode *m_null;  
};  
//构造函数  
RBTree::RBTree()  
{  
    m_null = new RBNode;  
    m_null->color = black;  
    m_null->llink = m_null->rlink = m_null;  
    root = m_null;  
}  
//析构函数  
RBTree::~RBTree()  
{  
    if (root != m_null)  
    {  
        destroy(&root);  
        root = NULL;  
    }  
    delete m_null;  
    m_null = NULL;  
}  
//插入元素  
int RBTree::insertNode(int key)  
{  
    RBNode *p = root;  
    RBNode *parent = m_null;  
    while (p != m_null)  
    {  
        parent = p;  
        if (key == p->key)  
        {  
            return -1;  
        }  
        else if (key < p->key)  
        {  
            p = p->llink;  
        }  
        else  
        {  
            p = p->rlink;  
        }  
    }  
    RBNode *newNode = createNode(key);  
    if (parent == m_null)  
    {  
        root = newNode;  
        root->color = black;  
    }  
	else
	{
	    if (key < parent->key)  
	    {  
	        parent->llink = newNode;  
	    }  
	    else  
	    {  
	        parent->rlink = newNode;  
	    }  
	    newNode->parent = parent;  
	    insertFixup(newNode);              //插入元素后调整  
	}
    return 0;
}  
//插入元素后调整  
void RBTree::insertFixup(RBNode *pnode)  
{  
    RBNode *parent = pnode->parent;  
    RBNode *grandParent = m_null;  
    while (parent != m_null&&parent->color == red)      //迭代  
    {  
        grandParent = parent->parent;  
        if (parent == grandParent->llink)  
        {  
            RBNode *uncle = grandParent->rlink;  
            if (uncle->color == red)                                //情况1  
            {  
                parent->color = black;  
                uncle->color = black;  
                grandParent->color = red;  
                pnode = grandParent;  
                parent = pnode->parent;  
            }  
            else  
            {  
                if (pnode == parent->rlink)                        //情况2,可转换为情况3  
                {  
                    pnode = rotate_left(parent);  
                    parent = pnode->parent;  
                    grandParent = parent->parent;  
                }  
                parent->color = black;                            //情况3  
                grandParent->color = red;  
                rotate_right(grandParent);  
            }  
        }  
        else                                                      //与上面对称  
        {  
            RBNode *uncle = grandParent->llink;  
            if (uncle->color == red)  
            {  
                parent->color = black;  
                uncle->color = black;  
                grandParent->color = red;  
                pnode = grandParent;  
                parent = pnode->parent;  
            }  
            else  
            {  
                if (pnode == parent->llink)  
                {  
                    pnode = rotate_right(parent);  
                    parent = pnode->parent;  
                    grandParent = parent->parent;  
                }  
                parent->color = black;  
                grandParent->color = red;  
                rotate_left(grandParent);  
            }  
        }  
    }  
    root->color = black;  
}  
//寻找指定键值元素  
RBNode *RBTree::searchNode(int key)  
{  
    RBNode *p = root;  
    while (p != m_null)  
    {  
        if (key == p->key)  
        {  
            return p;  
        }  
        else if (key < p->key)  
        {  
            p = p->llink;  
        }  
        else  
        {  
            p = p->rlink;  
        }  
    }  
    return m_null;  
}  
//删除元素后调整各结点关系  
void RBTree::transplant(RBNode *v0, RBNode *v1)  
{  
    if (v0 == root)  
    {  
        root = v1;  
		root->parent=m_null;
    }  
    else if (v0 == v0->parent->llink)  
    {  
        v0->parent->llink = v1;  
    }  
    else  
    {  
        v0->parent->rlink = v1;  
    }  
    v1->parent = v0->parent;  
}  
//找到树中最小健值结点  
RBNode *RBTree::minNode(RBNode *x)  
{  
    while (x->llink != m_null)  
    {  
        x = x->llink;  
    }  
    return x;  
}  
//删除指定健值结点  
int RBTree::deleteNode(int key)  
{  
    RBNode *delNode = searchNode(key);            //寻找删除的结点  
    if (delNode == m_null)  
    {  
        return -1;  
    }  
    RBNode *realDel = delNode;                  //实际删除的结点赋初值  
    RBNode *replace = m_null;                   //代替的结点  
    if (delNode->rlink == m_null)               //如果删除的结点最多只有1棵子树  
    {  
        replace = delNode->llink;  
    }  
    else if (delNode->llink == m_null)  
    {  
        replace = delNode->rlink;  
    }  
    else                                       //如果有两个子树  
    {  
        realDel = minNode(delNode->rlink);     //找到右子树最小结点,即为实际要删除的结点  
        replace = realDel->rlink;  
        delNode->key = realDel->key;           //实际删除的结点值赋给删除的结点  
    }  
    transplant(realDel, replace);  
    if (realDel->color == black)  
    {  
        deleteFixup(replace);             //如果实际删除的结点是黑色,则调整  
    }  
    delete realDel;  
	return 0;
}  

//删除结点后调整  
void RBTree::deleteFixup(RBNode *delNode)  
{  
    RBNode *p = delNode;  
  
    while (p != root&&p->color == black)  
    {  
        RBNode *parent = p->parent;  
        if (p == parent->llink)  
        {  
            RBNode *slibing = parent->rlink;  
            if (slibing->color == red)                                       //情况1,兄弟结点为红色 可转换为情况2,3,4  
            {                                                               //兄弟结点涂成黑色,父结点凃成红色,以父结点为支点左旋   
                parent->color = red;  
                slibing->color = black;  
                rotate_left(parent);  
                slibing = parent->rlink;                                     //调整兄弟结点  
            }  
            //此时兄弟结点肯定为黑色  
            if (slibing->llink->color == black&&slibing->rlink->color == black)       //情况2,两个侄子结点都为黑色  
            {  
                slibing->color = red;                                        //兄弟结点凃红  
                p = parent;                                               	 //父结点为当前节点  
            }  
            else  
            {  
                if (slibing->rlink->color == black)                                 //情况3,左侄子结点为红色  
                {  
                    slibing->color = red;                                    //兄弟凃红  
                    slibing->llink->color = black;                           //左侄子凃红  
                    rotate_right(slibing);                                   //以兄弟为支点右旋  
                    slibing = slibing->parent;                               //调整兄弟结点转换为情况4  
                }  
                slibing->color = parent->color;                               //情况4 ,右侄子为红  
                parent->color = black;                                       //父结点与兄弟结点交换颜色  
                slibing->rlink->color = black;                                //右侄子凃黑后结束  
                rotate_left(parent);                                        //以父结点为支点左旋  
                p = root;                                                   
            }  
        }  
        else                                                                 //与上面对称  
        {  
            RBNode *slibing = parent->llink;  
            if (slibing->color == red)  
            {  
                slibing->color = black;  
                parent->color = red;  
                rotate_right(parent);  
                slibing = parent->llink;  
            }  
            if (slibing->llink->color == black&&slibing->rlink->color == black)  
            {  
                slibing->color = red;  
                p = parent;  
            }  
            else  
            {  
                if (slibing->llink->color == black)  
                {  
                    slibing->color = red;  
                    slibing->rlink->color = black;  
                    rotate_left(slibing);  
                    slibing = slibing->parent;  
                }  
                slibing->color = parent->color;  
                parent->color = black;  
                slibing->llink->color = black;  
                rotate_right(parent);  
                p = root;  
            }  
        }  
    }  
    p->color = black;  
}  
//右旋 				
RBNode *RBTree::rotate_right(RBNode *a)  
{  
    RBNode *b = a->llink;  
    if (b == m_null)  
    {  
        return a;  
    }  
    a->llink = b->rlink;  
    b->rlink->parent = a;  
    if (root == a)  
    {  
        root = b;  
        b->parent = m_null;  
    }  
    else  
    {  
        if (a->parent->llink == a)  
        {  
            a->parent->llink = b;  
        }  
        else  
        {  
            a->parent->rlink = b;  
        }  
        b->parent = a->parent;  
    }  
    b->rlink = a;  
    a->parent = b;  
    return a;  
}  
//左旋  
RBNode *RBTree::rotate_left(RBNode *a)  
{  
    RBNode *b = a->rlink;  
    if (b == m_null)  
    {  
        return a;  
    }  
    a->rlink = b->llink;  
    b->llink->parent = a;  
    if (root == a)  
    {  
        root = b;  
        b->parent = m_null;  
    }  
    else  
    {  
        if (a->parent->llink == a)  
        {  
            a->parent->llink = b;  
        }  
        else  
        {  
            a->parent->rlink = b;  
        }  
        b->parent = a->parent;  
    }  
    b->llink = a;  
    a->parent = b;  
    return a;  
}  
//销毁树,析构函数调用  
void RBTree::destroy(RBNode **proot)  
{  
    if (*proot == m_null)  
    {  
        return;  
    }  
    destroy(&(*proot)->llink);  
    destroy(&(*proot)->rlink);  
    delete *proot;  
    *proot = m_null;  
}  
RBNode *RBTree::createNode(int key)  
{  
    RBNode *p = new RBNode;  
    if (p)  
    {  
        p->color = red;  
        p->key = key;  
        p->llink = p->rlink = p->parent = m_null;  
    }  
    return p;  
}  
//先序遍历非递归  
void RBTree::nPreOrder()  
{  
    if (root == m_null)  
    {  
        return;  
    }  
    stack<RBNode*> st;  
    RBNode *p = root;  
    st.push(p);  
    while (!st.empty())  
    {  
        p = st.top();  
        st.pop();  
        if (p != m_null)  
        {  
            cout << p->key << ' ';  
            st.push(p->rlink);  
            st.push(p->llink);  
        }  
    }  
    cout << endl;  
}  
//中序遍历非递归  
void RBTree::nInOrder()  
{  
    if (root == m_null)  
    {  
        return;  
    }  
    stack<RBNode*> st;  
    RBNode *p = root;  
    while (p != m_null || !st.empty())  
    {  
        while (p != m_null)  
        {  
            st.push(p);  
            p = p->llink;  
        }  
        p = st.top();  
        st.pop();  
        cout << p->key << ' ';  
        p = p->rlink;  
    }  
    cout << endl;  
}  
//后序遍历非递归  
void RBTree::nPostOrder()  
{  
    if (root == m_null)  
    {  
        return;  
    }  
    stack<RBNode*> st;  
    RBNode *p = root;  
    RBNode *pp = m_null;  
    while (p != m_null || !st.empty())  
    {  
        while (p != m_null)  
        {  
            st.push(p);  
            pp = p->rlink;  
            p = p->llink;  
            if (p == m_null)  
            {  
                p = pp;  
            }  
        }  
        p = st.top();  
        st.pop();  
        cout << p->key << ' ';  
        if (!st.empty() && st.top()->llink == p)  
        {  
            p = st.top()->rlink;  
        }  
        else  
        {  
            p = m_null;  
        }  
    }  
    cout << endl;  
}  
//判断是否是红黑树
bool RBTree::isRBTree()
{
	if (root == m_null)  
    {  
        return true;  
    }  
	vector<RBNode*> st;
	RBNode *p=root;
	RBNode *pp=m_null;
	int num=0;
	int black_num=0;
	//1、根节点是黑色
	if(p->color==red)                          
		return false;
	while(p!=m_null||!st.empty())
	{
		while(p!=m_null)
		{
			st.push_back(p);
			pp=p->rlink;
			p=p->llink;
			if(p==m_null)
				p=pp;
		}
		p=st.back();
		st.pop_back();
		//2、每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
		if(p->color==red&&(p->llink->color!=black||p->rlink->color!=black))
			return false;
		//3、从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点
		if(p->llink==m_null&&p->rlink==m_null)
		{
			black_num=0;
			for(vector<RBNode*>::iterator iter=st.begin();iter!=st.end();++iter)
			{
				if((*iter)->color==black)
					black_num++;
			}
			if(p->color==black)
				black_num++;
			if(num==0)
				num=black_num;
			else if(num!=black_num)
				return false;
		}

		if(!st.empty()&&st.back()->llink==p)
			p=st.back()->rlink;
		else
			p=m_null;
	}
	return true;
}
#include<stdlib.h>
#define N 1000
#define random(i) (rand()%i)
int main()  
{  
    RBTree tree;  
    int num=0;
	while(num<N)       //插入N个不同的随机节点
	{
		if(tree.insertNode(random(N))==0)
		{
			num++;
			if(tree.isRBTree()==false)                //插入节点后判断是否是红黑树
				cout<<"insert error"<<endl;
		}
	}
    tree.nPreOrder(); 
	cout<<"======================"<<endl;
    tree.nInOrder();  
	cout<<"======================"<<endl;
    tree.nPostOrder();  
	cout<<"======================"<<endl;

	num=0;
	while(num<N)      //删除N个不同的随机节点
	{
		if(tree.deleteNode(random(N))==0)
		{
			num++;
			if(tree.isRBTree()==false)               //删除节点后判断是否是红黑树
				cout<<"delete error"<<endl;
		}
	}
    return 0;  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值