红黑书(三)红黑树的删除操作

c++完整代码(带插入、删除、查找等):


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

//颜色枚举;
enum _color
{
    _None,
    _Red,
    _Black
};
//结点结构;
struct tNode
{
    int iKey;
    int iColor;
    tNode* pParent;
    tNode* pLeft;
    tNode* pRight;

    tNode():
    iKey(NULL),
    iColor(_None),
    pParent(nullptr),
    pLeft(nullptr),
    pRight(nullptr)
    {

    }

};

class RBTree
{
public:
    RBTree():
    m_pRoot(nullptr),
    m_iCount(0)
    {
        m_pSentryNULL = new tNode();
        m_pSentryNULL->iColor = _Black;         //哨兵的颜色为黑色;
        m_pRoot = m_pSentryNULL;
    }
    ~RBTree()
    {
        delete m_pSentryNULL;
        m_pSentryNULL = nullptr;
    }
private:
    //根结点;
    tNode*          m_pRoot;
    //哨兵;
    tNode*          m_pSentryNULL;
    //元素数量;
    int             m_iCount;
private:
    //左旋;
    void left_Rotate(tNode* pNode)
    {
        if(pNode == nullptr||pNode == m_pSentryNULL||pNode->pRight == m_pSentryNULL)
        {
            return;
        }


        pNode->pRight->pParent = pNode->pParent;

        if (pNode->pParent == m_pSentryNULL)
        {
            m_pRoot = pNode->pRight;

        }
        else
        {
            if (pNode == pNode->pParent->pLeft)
            {
                pNode->pParent->pLeft = pNode->pRight;
            }
            else
            {
                pNode->pParent->pRight = pNode->pRight;
            }
        }
        pNode->pParent = pNode->pRight;

        if (pNode->pParent->pLeft == m_pSentryNULL)
        {
            pNode->pRight = m_pSentryNULL;
        }
        else
        {
            pNode->pRight->pLeft->pParent = pNode;
            pNode->pRight = pNode->pParent->pLeft;
        }

        pNode->pParent->pLeft = pNode;
    }
    //右旋;
    void right_Rotate(tNode* pNode)
    {
        if(pNode == nullptr||pNode == m_pSentryNULL||pNode->pLeft == m_pSentryNULL)
        {
            return;
        }

        pNode->pLeft->pParent = pNode->pParent;

        if (pNode->pParent == m_pSentryNULL)
        {
            m_pRoot = pNode->pLeft;

        }
        else
        {
            if (pNode == pNode->pParent->pLeft)
            {
                pNode->pParent->pLeft = pNode->pLeft;
            }
            else
            {
                pNode->pParent->pRight = pNode->pLeft;
            }
        }
        pNode->pParent = pNode->pLeft;
        if (pNode->pParent->pRight == m_pSentryNULL)
        {
            pNode->pLeft = m_pSentryNULL;
        }
        else
        {
            pNode->pLeft->pRight->pParent = pNode;
            pNode->pLeft = pNode->pParent->pRight;
        }
        pNode->pParent->pRight = pNode;

    }
    //插入调整;
    void RB_Insert_Fixup(tNode* pNode)
    {
        while (pNode->pParent->iColor == _Red)
        {
            if (pNode->pParent == pNode->pParent->pParent->pLeft)
            {
                tNode* pUncleNode = pNode->pParent->pParent->pRight;
                if (pUncleNode->iColor == _Red)//叔结点为红色;
                {
                    pUncleNode->iColor = _Black;
                    pNode->pParent->iColor = _Black;
                    pNode->pParent->pParent->iColor = _Red;
                    pNode = pNode->pParent->pParent;
                }
                else//叔结点为黑色;
                {
                    if (pNode == pNode->pParent->pRight)
                    {
                        pNode = pNode->pParent;
                        left_Rotate(pNode);
                    }
                    pNode->pParent->iColor = _Black;
                    pNode->pParent->pParent->iColor = _Red;
                    right_Rotate(pNode->pParent->pParent);

                }
            }
            else//对称操作
            {
                tNode* pUncleNode = pNode->pParent->pParent->pLeft;
                if (pUncleNode->iColor == _Red)//叔结点为红色;
                {
                    pUncleNode->iColor = _Black;
                    pNode->pParent->iColor = _Black;
                    pNode->pParent->pParent->iColor = _Red;
                    pNode = pNode->pParent->pParent;
                }
                else//叔结点为黑色;
                {
                    if (pNode == pNode->pParent->pLeft)
                    {
                        pNode = pNode->pParent;
                        right_Rotate(pNode);
                    }
                    pNode->pParent->iColor = _Black;
                    pNode->pParent->pParent->iColor = _Red;
                    left_Rotate(pNode->pParent->pParent);

                }
            }
        }

        m_pRoot->iColor = _Black;
    }

    //删除调整;
    void RB_Delete_Fixup(tNode* pNode)
    {
        while (pNode!=m_pRoot&&pNode->iColor == _Black)
        {
            if (pNode == pNode->pParent->pLeft)
            {
                tNode* pBrotherNode = pNode->pParent->pRight;   //兄弟结点;
                if (pBrotherNode->iColor == _Red)
                {
                    pNode->pParent->iColor = _Red;
                    pBrotherNode->iColor = _Black;
                    left_Rotate(pNode->pParent);
                    pBrotherNode = pBrotherNode->pParent->pRight;
                }

                if (pBrotherNode->iColor == _Black)
                {
                    if (pBrotherNode->pLeft->iColor == _Black&&pBrotherNode->pRight->iColor == _Black)
                    {
                        pBrotherNode->iColor = _Red;
                        pNode = pNode->pParent;
                    }
                    else
                    {
                        if(pBrotherNode->pRight->iColor == _Black)
                        {
                            pBrotherNode->iColor = _Red;
                            pBrotherNode->pLeft->iColor = _Black;
                            right_Rotate(pBrotherNode);
                            pBrotherNode = pNode->pParent->pRight;
                        }

                        pBrotherNode->iColor = pNode->pParent->iColor;
                        pNode->pParent->iColor = _Black;
                        pBrotherNode->pRight->iColor = _Black;
                        left_Rotate(pNode->pParent);
                        pNode = m_pRoot;
                    }

                }
            }
            else//对称操作;
            {

                tNode* pBrotherNode = pNode->pParent->pLeft;   //兄弟结点;
                if (pBrotherNode->iColor == _Red)
                {
                    pNode->pParent->iColor = _Red;
                    pBrotherNode->iColor = _Black;
                    right_Rotate(pNode->pParent);
                    pBrotherNode = pBrotherNode->pParent->pLeft;
                }

                if (pBrotherNode->iColor == _Black)
                {
                    if (pBrotherNode->pRight->iColor == _Black&&pBrotherNode->pLeft->iColor == _Black)
                    {
                        pBrotherNode->iColor = _Red;
                        pNode = pNode->pParent;
                    }
                    else
                    {
                        if(pBrotherNode->pLeft->iColor == _Black)
                        {
                            pBrotherNode->iColor = _Red;
                            pBrotherNode->pRight->iColor = _Black;
                            left_Rotate(pBrotherNode);
                            pBrotherNode = pNode->pParent->pLeft;
                        }

                        pBrotherNode->iColor = pNode->pParent->iColor;
                        pNode->pParent->iColor = _Black;
                        pBrotherNode->pLeft->iColor = _Black;
                        right_Rotate(pNode->pParent);
                        pNode = m_pRoot;
                    }

                }

            }
        }
        pNode->iColor = _Black;
    }
    //返回最小关键字元素;
    tNode* minNode(tNode* rootNode)
    {
        if(rootNode == m_pSentryNULL) return m_pSentryNULL;

        while (rootNode->pLeft!=m_pSentryNULL)
        {
            rootNode = rootNode->pLeft;
        }

        return rootNode;
    }
    //返回最大关键字元素;
    tNode* maxNode(tNode* rootNode)
    {
        if(rootNode == m_pSentryNULL) return m_pSentryNULL;

        while (rootNode->pRight!=m_pSentryNULL)
        {
            rootNode = rootNode->pRight;
        }

        return rootNode;
    }

    //替换子树;
    void transplantNode(tNode* pDesNode,tNode* pSrcNode)
    {
        if (pDesNode->pParent == m_pSentryNULL)
        {
            m_pRoot = pSrcNode;
        }
        else if(pDesNode == pDesNode->pParent->pLeft)
        {
            pDesNode->pParent->pLeft = pSrcNode;
        }
        else
        {
            pDesNode->pParent->pRight = pSrcNode;
        }

        pSrcNode->pParent = pDesNode->pParent;
    }
public:
    //查询数据;
    tNode* search(int iKey)
    {
        tNode* pTemp = m_pRoot;
        while(pTemp!=m_pSentryNULL&&iKey!=pTemp->iKey)
        {
            if (iKey<pTemp->iKey)
            {
                pTemp = pTemp->pLeft;
            }
            else
            {
                pTemp = pTemp->pRight;
            }
        }
        return pTemp;
    }

    //插入;
    void RB_Insert(tNode* pNode)
    {
        if(pNode == m_pSentryNULL)
        {
            return;
        }
        //二叉搜索树插入操作;
        tNode* pTemp = m_pRoot;
        tNode* pTempParent = m_pSentryNULL;
        while (pTemp!=m_pSentryNULL)
        {
            pTempParent = pTemp;
            if (pNode->iKey<pTemp->iKey)
            {
                pTemp = pTemp->pLeft;
            }
            else
            {
                pTemp = pTemp->pRight;
            }
        }

        pNode->pParent = pTempParent;

        if (m_pRoot == m_pSentryNULL)
        {
            m_pRoot = pNode;
        }
        else
        {
            if (pNode->iKey < pTempParent->iKey)
            {
                pTempParent->pLeft = pNode;
            }
            else
            {
                pTempParent->pRight = pNode;
            }
        }
        pNode->pLeft = m_pSentryNULL;
        pNode->pRight = m_pSentryNULL;
        pNode->iColor = _Red;
        m_iCount++;
        //调整以保持红黑性质;
        RB_Insert_Fixup(pNode);
    }
    //删除;
    void RB_Delete(tNode* pNode)
    {
        if (m_pRoot == m_pSentryNULL||pNode == m_pSentryNULL)
        {
            return;
        }

        int iDeleteColor = pNode->iColor;       //要删除的结点颜色;
        tNode* pSrcNode = nullptr;              //纪录替换删除位置的结点;

        if(pNode->pLeft == m_pSentryNULL)//左子结点不存在;
        {
            pSrcNode = pNode->pRight;
            transplantNode(pNode,pNode->pRight);
            cout<<"delete success!"<<endl;
        }
        else if(pNode->pRight == m_pSentryNULL)//左子结点存在,右子结点不存在;
        {
            pSrcNode = pNode->pLeft;
            transplantNode(pNode,pNode->pLeft);
            cout<<"delete success!"<<endl;
        }
        else//左右子结点都存在;
        {
            tNode* pSuccessor =minNode(pNode->pRight);//后继;
            iDeleteColor = pSuccessor->iColor;
            pSrcNode = pSuccessor->pRight;
            if (pSuccessor!=pNode->pRight)
            {
                transplantNode(pSuccessor, pSuccessor->pRight);
                pSuccessor->pRight = pNode->pRight;
                pSuccessor->pRight->pParent = pSuccessor;
            }
            transplantNode(pNode,pSuccessor);
            pSuccessor->pLeft = pNode->pLeft;
            pSuccessor->pLeft->pParent = pSuccessor;
            pSuccessor->iColor = pNode->iColor;
            cout<<"delete success!"<<endl;
        }

        m_iCount--;
        if (iDeleteColor == _Black)
        {
            RB_Delete_Fixup(pSrcNode);
        }
        delete pNode;
        pNode = nullptr;
    }
    //前驱;
    tNode* predecessorNode(tNode* pNode)
    {
        if (pNode->pLeft!=m_pSentryNULL)
        {
            return maxNode(pNode->pLeft);
        }
        tNode* pTemp = pNode->pParent;

        while (pTemp!=m_pSentryNULL&&pTemp->pLeft == pNode)
        {
            pNode = pTemp;
            pTemp = pTemp->pParent;
        }
        return pTemp;
    }
    //后继;
    tNode* successorNode(tNode* pNode)
    {
        if (pNode->pRight!=m_pSentryNULL)
        {
            return minNode(pNode->pRight);
        }
        tNode* pTemp = pNode->pParent;

        while (pTemp!=m_pSentryNULL&&pTemp->pRight == pNode)
        {
            pNode = pTemp;
            pTemp = pTemp->pParent;
        }
        return pTemp;
    }

    //获得最小的元素值;
    const int& getMinValue()
    {
        tNode* pTemp = minNode(m_pRoot);
        if (pTemp!=m_pSentryNULL)
        {
            return pTemp->iKey;
        }
        else
        {
            return NULL;
        }
    }
    //获得最大的元素值;
    const int& getMaxValue()
    {
        tNode* pTemp = maxNode(m_pRoot);
        if (pTemp!=m_pSentryNULL)
        {
            return pTemp->iKey;
        }
        else
        {
            return NULL;
        }
    }


    //判断红黑树是否为空;
    bool empty()
    {
        if (m_iCount == 0)
        {
            return true;
        }
        return false;
    }
    //插入元素;
    void push(int iData)
    {
        tNode* pNode = new tNode;
        if (pNode)
        {
            pNode->iKey = iData;
            RB_Insert(pNode);
        }
    }
    //获得元素数目;
    const int& size()
    {
        return m_iCount;
    }
    //遍历;
    void traversal()
    {
        //中序遍历;
        if (m_pRoot == m_pSentryNULL)
        {
            return;
        }

        stack<tNode*> _stack;
        tNode* pTemp = m_pRoot;
        while (m_pSentryNULL!=pTemp||!_stack.empty())
        {
            if (m_pSentryNULL!=pTemp)
            {
                _stack.push(pTemp);
                pTemp = pTemp->pLeft;
            }
            else
            {
                pTemp = _stack.top();
                cout<<pTemp->iKey<<"    "<<pTemp->iColor<<endl;
                _stack.pop();
                pTemp = pTemp->pRight;
            }
        }
    }


};


//测试代码;
RBTree _rbTree;

cout<<"empty "<<_rbTree.empty()<<endl;

_rbTree.push(11);
_rbTree.push(7);
_rbTree.push(5);
_rbTree.push(12);
_rbTree.push(6);
cout<<"empty "<<_rbTree.empty()<<endl;

//cout<<"size  "<<_rbTree.size()<<endl;
//_rbTree.traversal();

_rbTree.RB_Delete(_rbTree.search(7));
cout<<"size  "<<_rbTree.size()<<endl;
_rbTree.traversal();
//测试代码输出;
empty 1
empty 0
delete success!
size  4
5    2
6    1
11    2
12    2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值