红黑树的基本操作



template<class K, class V>
class RBTree
{
    typedef RBTreeNode<K, V> Node;

public:

    RBTree()
        :_pRoot(NULL)
    {}

    //插入
    bool Insert(const K& key, const V& value)
    {
        return _Insert(_pRoot,key,value);
    }

    void InOrder()
    {
        _InOrder(_pRoot);
        cout << endl;
    }

    bool CkeckBRTree()
    {
        return _CheckRBTree(_pRoot);
    }
protected:

    //插入
    bool _Insert(Node*& pRoot, const K& key, const V& value)
    {
        if (NULL == pRoot)
        {
            _pRoot = new Node(key, value, BLACK);
            return false;
        }
        else
        {
            //找插入位置
            Node* pCur = _pRoot;
            Node* pParent = NULL;
            while (pCur)
            {
                if (key < pCur->_key)
                {
                    pParent = pCur;
                    pCur = pCur->_pLeft;
                }
                else if (key > pCur->_key)
                {
                    pParent = pCur;
                    pCur = pCur->_pRight;
                }
                else
                    return false;
            }
            //插入节点
            pCur = new Node(key, value);
            if (key < pParent->_key)
                pParent->_pLeft = pCur;
            else
                pParent->_pRight = pCur;

            pCur->_pParent = pParent;

            //用性质来跟新颜色
            while (pCur != pRoot && RED == pParent->_color)//存在pParent结点,且pParent结点存在双亲结点
            {
                Node* pGrandparent = pParent->_pParent;
                if (pParent == pGrandparent->_pLeft)
                {
                    Node* pUncle = pGrandparent->_pRight;
                    if (pUncle && RED == pUncle->_color)             //叔叔结点存在,且为红色
                    {
                        pUncle->_color = pParent->_color = BLACK;
                        pGrandparent->_color = RED;

                        pCur = pGrandparent;
                        pParent = pCur->_pParent;
                    }
                    else //pCur为红色,且pParent为红色,叔叔结点可以存在,且为黑色,或者不存在  //右单旋,或者左右双旋
                    {
                        if (pCur == pParent->_pRight) //情况五,先左单选,再右单选  //先改变为情况四
                        {
                            _RotateLeft(pParent);
                            swap(pParent, pCur);//旋转之后,pcur和pparent的位置发生过改变,需要再次进行交换,以方便后面该颜色
                        }

                        _RotateRight(pGrandparent); //改变双亲结点为黑色,祖父结点为红色
                        pParent->_color = BLACK;
                        pGrandparent->_color = RED;
                    }
                }
                else  //和上面的情况相反的方向
                {
                    Node* pUncle = pGrandparent->_pLeft;
                    if (pUncle && RED == pUncle->_color)
                    {
                        pUncle->_color = pParent->_color = BLACK;
                        pGrandparent->_color = RED;

                        pCur = pGrandparent;  //继续向上跟新
                        pParent = pCur->_pParent;
                    }
                    else  //情况四和情况五
                    {

                        if (pCur == pParent->_pLeft)
                        {
                            _RotateRight(pParent); //右单旋
                            swap(pParent, pCur);   //交换指针
                        }

                        _RotateLeft(pGrandparent);
                        pParent->_color = BLACK;
                        pGrandparent->_color = RED;
                    }
                }
                _pRoot->_color = BLACK;
                return true;
            }
        }
    }

    bool _CheckRBTree(Node* pRoot)
    {
        //1.每个根结点都是黑色的
        if (pRoot->_color == RED)
            return false;

        int count = 0;
        Node* pCur = pRoot;
        while (pCur)
        {
            if (BLACK == pCur->_color)
                count++;
            pCur = pCur->_pLeft;
        }

        int k = 0;
        return _CheckRBTree(pRoot, count, k);
    }

protected:

    void _RotateRight(Node*& pParent)
    {
        Node* pSubL = pParent->_pLeft;
        Node* pSubLR = pSubL->_pRight;
        pParent->_pLeft = pSubLR;
        pSubL->_pRight = pParent;
        if (pSubLR)
            pSubLR->_pParent = pParent;

        Node* pPParent = pParent->_pParent;
        pSubL->_pParent = pPParent;
        if (pPParent)
        {
            if (pPParent->_pLeft == pParent)
                pPParent->_pLeft = pSubL;
            else
                pPParent->_pRight = pSubL;
        }
        else
            _pRoot = pSubL;

        pParent->_pParent = pSubL;
    }

    void _RotateLeft(Node*& pParent)
    {
        Node* pSubR = pParent->_pRight;
        Node* pSubRL = pSubR->_pLeft;
        pParent->_pRight = pSubRL;
        pSubR->_pLeft = pParent;
        if (pSubRL)
            pSubRL->_pParent = pParent;

        Node* pPParent = pParent->_pParent;
        pSubR->_pParent = pPParent;
        if (pPParent)
        {
            if (pPParent->_pLeft == pParent)
                pPParent->_pLeft = pSubR;

            else
                pPParent->_pRight = pSubR;

        }
        else
            _pRoot = pSubR;

        pParent->_pParent = pSubR;
    }

    void _InOrder(Node*& pRoot)
    {
        if (pRoot)
        {
            _InOrder(pRoot->_pLeft);
            cout << pRoot->_key << " color:" << pRoot->_color << endl;;
            _InOrder(pRoot->_pRight);
        }
    }

    bool _CheckRBTree(Node* pRoot, int count, int k)
    {
        if (NULL == pRoot)
            return true;

        if (RED == pRoot->_color && RED == pRoot->_pParent->_color)
            return false;
        if (BLACK == pRoot->_color)
            k++;
        if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight)
        {
            if (k == count)
                return true;
            else
                return false;
        }
        return _CheckRBTree(pRoot->_pLeft, count, k) && _CheckRBTree(pRoot->_pRight, count, k);
    }

protected:
    Node* _pRoot;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值