• 红黑树研究记录代码实现


    代码可以根据《红黑树研究记录-实例》那篇文章的图来验证

    main.cpp

    #include <iostream.h>
    #include "RBTree.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        int arr[20] = {12, 1, 9, 2, 0, 11, 7, 19, 4, 15, 18, 5, 14, 13, 10, 16, 6, 3, 8, 17};
        RBTree *tree = new RBTree();
        for(int i = 0; i < 20; i++)
            tree->InsertNode(arr[i]);
        
        
        std::cout<<"PreOrder:"<<std::endl;
        tree->PreOrder();
        std::cout<<"InOrder:"<<std::endl;
        tree->InOrder();
        std::cout<<"PostOrder:"<<std::endl;
        tree->PostOrder();
        
        std::cout<<std::endl<<"Delete Node:"<<std::endl;
        cout<<"Delete 12:"<<endl;
        tree->DeleteNode(12);
        tree->PreOrder();
        cout<<"Delete 1:"<<endl;
        tree->DeleteNode(1);
        tree->PreOrder();
        cout<<"Delete 9:"<<endl;
        tree->DeleteNode(9);
        tree->PreOrder();
        cout<<"Delete 2:"<<endl;
        tree->DeleteNode(2);
        tree->PreOrder();    
        cout<<"Delete 0:"<<endl;
        tree->DeleteNode(0);
        tree->PreOrder();
        cout<<"Delete 11:"<<endl;
        tree->DeleteNode(11);
        tree->PreOrder();
        cout<<"Delete 7:"<<endl;
        tree->DeleteNode(7);
        tree->PreOrder();
        cout<<"Delete 19:"<<endl;
        tree->DeleteNode(19);
        tree->PreOrder();
        cout<<"Delete 4:"<<endl;
        tree->DeleteNode(4);
        tree->PreOrder();
        cout<<"Delete 15:"<<endl;
        tree->DeleteNode(15);
        tree->PreOrder();    
        cout<<"Delete 18:"<<endl;
        tree->DeleteNode(18);
        tree->PreOrder();
        cout<<"Delete 5:"<<endl;
        tree->DeleteNode(5);
        tree->PreOrder();
        cout<<"Delete 14:"<<endl;
        tree->DeleteNode(14);
        tree->PreOrder();
        cout<<"Delete 13:"<<endl;
        tree->DeleteNode(13);
        tree->PreOrder();
        cout<<"Delete 10:"<<endl;
        tree->DeleteNode(10);
        tree->PreOrder();    
        cout<<"Delete 6:"<<endl;
        tree->DeleteNode(6);
        tree->PreOrder();
        cout<<"Delete 16:"<<endl;
        tree->DeleteNode(16);
        tree->PreOrder();
        cout<<"Delete 3:"<<endl;
        tree->DeleteNode(3);
        tree->PreOrder();
        cout<<"Delete 8:"<<endl;
        tree->DeleteNode(8);
        tree->PreOrder();
        cout<<"Delete 17:"<<endl;
        tree->DeleteNode(17);
        tree->PreOrder();
        return  0;
    }

    RBTree.h

    #ifndef _RBTREE_HEADER_
    #define _RBTREE_HEADER_
    
    #include <iostream.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    enum NodeColor{
        RED,
        BLACK
    };
    
    struct RBNode
    {
        int value;
        NodeColor color;
        RBNode *pParent;
        RBNode *pLeft;
        RBNode *pRight;
    };
    
    class RBTree
    {
    public:
        RBTree();
        ~RBTree();
        
        int InsertNode(int);
        int DeleteNode(int);
        RBNode *FindNode(int value);
        
        void PreOrder();
        void InOrder();
        void PostOrder();
    private:
        void DeleteAll();
        void TurnLeft(RBNode *pNode);
        void TurnRight(RBNode *pNode);
        int DeleteNode(RBNode *);
        RBNode *GetSuccessor(RBNode *);
        int InsertNode(RBNode *);
        void DeleteFixup(RBNode *);
        void InsertFixup(RBNode *);
    private:
        RBNode *m_root;
    };
    
    #endif

    RBTree.cpp

    #include "RBTree.h"
    #include <deque>
    #include <queue>
    
    using namespace std;
    
    RBTree::RBTree()
    {
        m_root = NULL;
    }
    
    RBTree::~RBTree()
    {
        DeleteAll();
    }
    
    void RBTree::TurnLeft(RBNode *pNode)
    {
        if(!pNode || !pNode->pParent)
            return;
        RBNode *pp = pNode->pParent->pParent;
        if(pp)
            if(pp->pLeft == pNode->pParent)
                pp->pLeft = pNode;
            else
                pp->pRight = pNode;
        pNode->pParent->pParent = pNode;
        pNode->pParent->pRight = pNode->pLeft;
        if(pNode->pLeft)
            pNode->pLeft->pParent = pNode->pParent;
        pNode->pLeft = pNode->pParent;    
        pNode->pParent = pp;    
    }
    
    void RBTree::TurnRight(RBNode *pNode)
    {
        if(!pNode || !pNode->pParent)
            return;
        RBNode *pp = pNode->pParent->pParent;
        if(pp)
            if(pp->pLeft == pNode->pParent)
                pp->pLeft = pNode;
            else
                pp->pRight = pNode;
        pNode->pParent->pParent = pNode;
        pNode->pParent->pLeft = pNode->pRight;
        if(pNode->pRight)
            pNode->pRight->pParent = pNode->pParent;
        pNode->pRight = pNode->pParent;    
        pNode->pParent = pp;
    }
    
    void RBTree::DeleteAll()
    {
        if(!m_root)
            std::cout<<"The tree is null"<<std::endl;
        queue<RBNode*> qu;
        qu.push(m_root);
        while(qu.size() > 0)
        {
            RBNode *pCur = qu.front();
            qu.pop();
            std::cout<<"Delete:"<<pCur->value<<"("<<pCur->color<<"), "<<std::endl;
            if(pCur->pLeft)
                qu.push(pCur->pLeft);
            if(pCur->pRight)
                qu.push(pCur->pRight);
            delete pCur;
            pCur = NULL;
        }
    }
    
    int RBTree::InsertNode(int value)
    {
        if(FindNode(value))
            return -1;
        RBNode *pNew = new RBNode();
        pNew->value = value;
        pNew->pParent = NULL;
        pNew->color = RED;
        pNew->pLeft = NULL;
        pNew->pRight = NULL;
        
        return InsertNode(pNew);
    }
    
    int RBTree::InsertNode(RBNode* pNode)
    {
        if(!pNode)
            return -1;
        if(!m_root)
        {
            m_root = pNode;
            m_root->color = BLACK;
            return 0;
        }
        RBNode *tmp = m_root;
        RBNode *tmpParent = NULL;
        while(tmp)
        {
            tmpParent = tmp;
            if(tmp->value > pNode->value)
                tmp = tmp->pLeft;
            else
                tmp = tmp->pRight;
        }
        if(tmpParent->value > pNode->value)
            tmpParent->pLeft = pNode;
        else
            tmpParent->pRight = pNode;
        pNode->pParent = tmpParent;
        
        InsertFixup(pNode);
    }
    
    void RBTree::InsertFixup(RBNode *pNode)
    {
        if(!pNode)
            return;
        RBNode *pUncle = NULL;
        while(pNode->pParent && pNode->pParent->color == RED)
        {
            if(pNode->pParent == pNode->pParent->pParent->pLeft)
            {
                pUncle = pNode->pParent->pParent->pRight;
                if(pUncle && pUncle->color == RED)            //case 1
                {
                    pNode->pParent->color = BLACK;
                    pUncle->color = BLACK;
                    pNode->pParent->pParent->color = RED;
                    pNode = pNode->pParent->pParent;
                }
                else
                {
                    if(pNode == pNode->pParent->pRight)        //case 2
                    {
                        TurnLeft(pNode);
                        pNode = pNode->pLeft;
                    }
                    pNode->pParent->color = BLACK;            //case 3
                    pNode->pParent->pParent->color = RED;
                    TurnRight(pNode->pParent);
                    if(!pNode->pParent->pParent)
                        m_root = pNode->pParent;
                }
            }
            else
            {
                pUncle = pNode->pParent->pParent->pLeft;
                if(pUncle && pUncle->color == RED)                    //case 1
                {
                    pNode->pParent->color = BLACK;
                    pUncle->color = BLACK;
                    pNode->pParent->pParent->color = RED;
                    pNode = pNode->pParent->pParent;
                }
                else
                {
                    if(pNode == pNode->pParent->pLeft)        //case 2
                    {
                        TurnRight(pNode);
                        pNode = pNode->pRight;
                    }
                    pNode->pParent->color = BLACK;            //case 3
                    pNode->pParent->pParent->color = RED;
                    TurnLeft(pNode->pParent);
                    if(!pNode->pParent->pParent)
                        m_root = pNode->pParent;
                }
            }
        }
        m_root->color = BLACK;
    }
    
    int RBTree::DeleteNode(int value)
    {
        RBNode *pNode = NULL;
        if(!(pNode = FindNode(value)))
            return -1;
        return DeleteNode(pNode);
    }
    
    RBNode *RBTree::GetSuccessor(RBNode *pNode)
    {
        RBNode *pThis = pNode->pRight;
        while(pThis->pLeft)
            pThis = pThis->pLeft;
        return pThis;
    }
    
    int RBTree::DeleteNode(RBNode *pNode)
    {
        if(!pNode)
            return -1;
        RBNode *pDel = NULL;
        RBNode *pThis = NULL;
        //search the Node
        if(!pNode->pLeft && !pNode->pRight)
        {
            pThis = pNode;
            pDel = pNode;
        }
        else if(!pNode->pLeft || !pNode->pRight)
            pDel = pNode;
        else
            pDel = GetSuccessor(pNode);
        
        //delete the Node
        if(pDel->pLeft)
            pThis = pDel->pLeft;
        else if(pDel->pRight)
            pThis = pDel->pRight;
        else
            pThis = pDel;
        
        if(pThis != pDel)
        {
            pThis->pParent = pDel->pParent;
            
            if(!pDel->pParent)
                m_root = pThis;
            else if(pDel == pDel->pParent->pLeft)
                pDel->pParent->pLeft = pThis;
            else
                pDel->pParent->pRight = pThis;
        }
        if(pDel != pNode)
            pNode->value = pDel->value;
        if(pDel->color == BLACK)
            DeleteFixup(pThis);
            
        if(pThis == pDel)
            if(pDel == pDel->pParent->pLeft)
                pDel->pParent->pLeft = NULL;
            else
                pDel->pParent->pRight = NULL;
        if(pDel == m_root)
            m_root = NULL;
        delete pDel;
        pDel = NULL;
    }
    
    void RBTree::DeleteFixup(RBNode *pNode)
    {
        RBNode *pBrother = NULL;
        while(pNode != m_root && pNode->color == BLACK)
        {
            if(pNode == pNode->pParent->pLeft)
            {
                pBrother = pNode->pParent->pRight;
                if(pBrother->color == RED)        //case 1
                {
                    pBrother->color = BLACK;
                    pNode->pParent->color = RED;
                    TurnLeft(pBrother);
                    pBrother = pNode->pParent->pRight;    
                }
                if((!pBrother->pLeft || pBrother->pLeft->color == BLACK) 
                    && (!pBrother->pRight || pBrother->pRight->color == BLACK))        //case 2
                {
                    pBrother->color = RED;
                    pNode = pNode->pParent;
                }
                else
                {
                    if(!pBrother->pRight || pBrother->pRight->color == BLACK)        //case 3
                    {
                        pBrother->pLeft->color = BLACK;
                        pBrother->color = RED;
                        TurnRight(pBrother->pLeft);
                        pBrother = pNode->pParent->pRight;
                    }
                    pBrother->color = pNode->pParent->color;    //case 4
                    pNode->pParent->color = BLACK;
                    pBrother->pRight->color = BLACK;
                    TurnLeft(pBrother);
                    pNode = m_root;
                }
            }
            else
            {
                pBrother = pNode->pParent->pLeft;
                if(pBrother->color == RED)        //case 1
                {
                    pBrother->color = BLACK;
                    pNode->pParent->color = RED;
                    TurnRight(pBrother);
                    pBrother = pNode->pParent->pLeft;
                }
                if((!pBrother->pLeft || pBrother->pLeft->color == BLACK) 
                    && (!pBrother->pRight || pBrother->pRight->color == BLACK))    //case 2
                {
                    pBrother->color = RED;
                    pNode = pNode->pParent;
                }
                else
                {
                    if(!pBrother->pLeft || pBrother->pLeft->color == BLACK)        //case 3
                    {
                        pBrother->pRight->color = BLACK;
                        pBrother->color = RED;
                        TurnLeft(pBrother->pRight);
                        pBrother = pNode->pParent->pLeft;
                    }
                    pBrother->color = pNode->pParent->color;
                    pNode->pParent->color = BLACK;
                    pBrother->pLeft->color = BLACK;
                    TurnRight(pBrother);
                    pNode = m_root;
                }
            }
        }
        pNode->color = BLACK;
    }
    
    RBNode *RBTree::FindNode(int value)
    {
        if(!m_root)
            return NULL;
        RBNode *tmp = m_root;
        while(tmp)
        {
            if(value > tmp->value)
                tmp = tmp->pRight;
            else if(value < tmp->value)
                tmp = tmp->pLeft;
            else
                break;
        }
        return tmp;
    }
    
    void RBTree::PreOrder()
    {
        if(!m_root)
        {
            std::cout<<"The tree is null"<<std::endl;
            return;
        }
        queue<RBNode*> qu;
        qu.push(m_root);
        while(qu.size() > 0)
        {
            RBNode *pCur = qu.front();
            qu.pop();
            std::cout<<pCur->value<<"("<<pCur->color<<"), ";
            if(pCur->pLeft)
                qu.push(pCur->pLeft);
            if(pCur->pRight)
                qu.push(pCur->pRight);
        }
        std::cout<<std::endl;
    }
    
    void RBTree::InOrder()
    {
        if(!m_root)
        {
            std::cout<<"The tree is null"<<std::endl;
            return;
        }
        
        deque<RBNode*> de;
        RBNode *pCur = m_root;
        bool bPush = false;
        
        while(pCur)
        {
            if(pCur->pLeft && !bPush)
            {
                de.push_back(pCur);
                pCur = pCur->pLeft;
                continue;
            }
            std::cout<<pCur->value<<"("<<pCur->color<<"), ";
            
            if(pCur->pRight)
            {
                pCur = pCur->pRight;
                bPush = false;
            }
            else
            {
                if(de.size() == 0)
                    break;
                pCur = de.back();
                de.pop_back();
                bPush = true;
            }
        }
        std::cout<<std::endl;
    }
    
    void RBTree::PostOrder()
    {
        if(!m_root)
        {
            std::cout<<"The tree is null"<<std::endl;
            return;
        }
        deque<RBNode*> de;
        int flag = 0;
        RBNode *pCur = m_root;
        while(pCur)
        {
            if(pCur->pLeft && flag < 1)
            {
                de.push_back(pCur);
                pCur = pCur->pLeft;
                continue;
            }
            if(pCur->pRight && flag < 2)
            {
                de.push_back(pCur);
                pCur = pCur->pRight;
                flag = 0;
                continue;
            }
            std::cout<<pCur->value<<"("<<pCur->color<<"), ";
            
            if(de.size() == 0)
                break;
            RBNode *pParent = de.back();
            de.pop_back();
            
            if(pCur == pParent->pLeft)
            {
                flag = 1;
                pCur = pParent;
            }
            else if(pCur == pParent->pRight)
            {
                flag = 2;
                pCur = pParent;
            }
        }
        std::cout<<std::endl;
    }
  • 相关阅读:
    01_垂直居中body中的应用
    C++基础知识易错点总结(2)
    辗转相除求最大公约数
    C++基础知识易错点总结(1)
    类对象的建立方式总结
    LeetCode(131)Palindrome Partitioning
    基本套接字编程(7) -- udp篇
    LeetCode(124) Binary Tree Maximum Path Sum
    LeetCode(115) Distinct Subsequences
    LeetCode(97) Interleaving String
  • 原文地址:https://www.cnblogs.com/geekma/p/2567718.html
Copyright © 2020-2023  润新知