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

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

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;

}

你可能感兴趣的:(红黑树)