紅黑樹源碼

Interface.h

#ifndef REDBLACKTREE_H
#define REDBLACKTREE_H
#include"DataType.h"
//紅黑樹
Interface IRedBlackTree
{ //插入節點
  virtual void InsertNode(int key,void*data)=0;
  //刪除節點
  virtual bool RemoveNode(int key)=0;
  //查詢節點
  virtual void* QueryNode(int key)=0;
};
extern "C" IRedBlackTree *GetCRedBlackTree(void);


CRedBlackTree.h

#ifndef CRDBLACKTREE_H
#define CRDBLACKTREE_H
#include"Interface.h"
 //數據節點
struct INode
{
   INode*            m_FNode;                    //父節點
   INode*            m_LNode;                    //左節點
   INode*            m_RNode;                    //右節點
   int               m_key;                      //箭值
   int               m_Coordinate;               //座標
   bool              m_Colour;                   //顏色
   void *            m_Data;                     //數據
   INode();
};
 //紅黑樹                    
 class CRedBlackTree:public IRedBlackTree
{   
  private: 
    INode *                   m_RootNode;                 //根節點
    INode *                   m_TemNode;                  //臨時節點
  public:
     CRedBlackTree();
    ~CRedBlackTree();
    //插入節點
    virtual void   InsertNode(int key,void*data);
    //刪除節點
    virtual bool   RemoveNode(int key);
    //查詢節點
    virtual void*  QueryNode(int key);
  private:
    //平衡節點
    void BalanceRedBlackTree(INode*Node);
    //平衡節點
    void RbDeleteFixup(INode*Node);    
    //左邊旋轉                 
    void LeftRotation(INode*Node);  
    //右邊旋轉                  
    void RightRotation(INode*Node);                      
};
#endif
CRedBlackTree.cpp
#include"CRedBlackTree.h"

#define NULL           0
#define LEFT           1
#define RIGHT          2
#define ROOT           0

IRedBlackTree* GetCRedBlackTree(void)
{
 return new CRedBlackTree;
}

INode::INode()
{
    m_LNode=NULL;
    m_LNode=NULL;
    m_RNode=NULL;
    m_key=0;
    m_Coordinate=0;
    m_Colour=true;
    m_Data=NULL;
}

CRedBlackTree::CRedBlackTree()
{
   //初始化
   m_RootNode==NULL;
   m_TemNode=new INode;
}
CRedBlackTree::~CRedBlackTree()
{

}
void CRedBlackTree::InsertNode(int key,void*data)
{
    //插入的是第一個節點直接設置爲根節點
    if(NULL==m_RootNode)
    {
        m_RootNode=new INode;
        m_RootNode->m_LNode=NULL;
        m_RootNode->m_RNode=NULL;
        m_RootNode->m_key=key;
        m_RootNode->m_Data=data;
        m_RootNode->m_Coordinate=0;
        m_RootNode->m_Colour=false;
        return ;
    }
    else
    {
        INode* TempNode=m_RootNode;
        while(NULL!=TempNode)
        {
            if(key<TempNode->m_key)
            {
                if(NULL==TempNode->m_LNode)
                {   INode*strNode=new INode;
                    TempNode->m_LNode=strNode;
                    strNode->m_FNode=TempNode;
                    strNode->m_RNode=NULL;
                    strNode->m_LNode=NULL;
                    strNode->m_Data=data;
                    strNode->m_key=key;
                    strNode->m_Coordinate=LEFT;

                    BalanceRedBlackTree(strNode);
                    return;
                }
                TempNode=TempNode->m_LNode;
            }
            else
            {
                if(NULL==TempNode->m_RNode)
                {   INode*strNode=new INode;
                    TempNode->m_RNode=strNode;
                    strNode->m_FNode=TempNode;
                    strNode->m_LNode=NULL;
                    strNode->m_RNode=NULL;
                    strNode->m_Coordinate=RIGHT;
                    strNode->m_key=key;
                    BalanceRedBlackTree(strNode);
                    return;
                }
                TempNode=TempNode->m_RNode;
            }
        }
    }
}
bool CRedBlackTree::RemoveNode(int key)
{
    INode* TempNode=m_RootNode;
    while(NULL!=TempNode)
    {
        if(key==TempNode->m_key)
        {
            INode* TempY=NULL;
            INode* TempX=NULL;
            if(NULL==TempNode->m_LNode||NULL==TempNode->m_RNode)
            {
                TempY=TempNode;
            }
            else
            {
                //記錄當前節點的後繼節點
                TempY=TempNode->m_RNode;
                while(TempY->m_LNode!=NULL)
                {
                    TempY=TempY->m_LNode;
                }
            }
            // 若TempY的左孩子不爲空 則將Tempy的左孩子 賦值給TempX
            if(NULL!=TempY->m_LNode)
                TempX=TempY->m_LNode;
            //否則TempY的右孩子賦值給TempX
            else
                TempX=TempY->m_RNode;

            if(NULL!=TempX)
            {
                TempX->m_FNode=TempY->m_FNode;
                TempX->m_Coordinate=TempY->m_Coordinate;
            }
            else
            {
                m_TemNode->m_Colour=false;
                m_TemNode->m_FNode=TempY->m_FNode;
                m_TemNode->m_Coordinate=TempY->m_Coordinate;
            }
            if(TempY->m_Coordinate==LEFT)
                TempY->m_FNode->m_LNode=TempX;
            else if(TempY->m_Coordinate==RIGHT)
                TempY->m_FNode->m_RNode=TempX;
            else if(TempY->m_Coordinate==ROOT)
                m_RootNode=TempX;
            //
            if(TempY!=TempNode)
            {
                TempNode->m_key=TempY->m_key;
                TempNode->m_Data=TempY->m_Data;
            }

            if(TempY->m_Colour==false)
            {
                RbDeleteFixup(TempX==NULL?m_TemNode:TempX);
            }
            delete TempY;
            return true;
        }
        else if(key<TempNode->m_key)
            TempNode=TempNode->m_LNode;
        else
            TempNode=TempNode->m_RNode;
    }
   return false;
}
void* CRedBlackTree::QueryNode(int key)
{
    INode* TempNode=m_RootNode;
    while(NULL!=TempNode)
     {
        if(key==TempNode->m_key)
        {
            return TempNode->m_Data;
        }
        else if(key<TempNode->m_key)
        {
            TempNode=TempNode->m_LNode;
        }
        else
        {
            TempNode=TempNode->m_RNode;
        }
     }
     return NULL;
}
void CRedBlackTree::BalanceRedBlackTree(INode*Node)
{
    INode*TempNode=Node->m_FNode;
    //
    bool FatherColour=TempNode->m_Colour;
    while(FatherColour)
    {
        //當前節點都爲紅色
        if(Node->m_Colour)
        {
            //查看叔叔節點的的顏色
            bool UncleColour=(TempNode->m_Coordinate==LEFT?
            (TempNode->m_FNode->m_RNode==NULL ? false :TempNode->m_FNode->m_RNode->m_Colour):
            (TempNode->m_FNode->m_LNode==NULL ? false:TempNode->m_FNode->m_LNode->m_Colour));
            //叔叔節點是紅色父節點是紅色當前節點是紅色
            if(UncleColour)
            {   //父節點是祖父節點的左節點
                if(TempNode->m_Coordinate==LEFT)
                  ((TempNode->m_FNode)->m_RNode)->m_Colour=false;
                else
                  ((TempNode->m_FNode)->m_LNode)->m_Colour=false;

                TempNode->m_Colour=false;
                TempNode->m_FNode->m_Colour=true;
                //將祖父節點設爲當前節點
                Node=TempNode->m_FNode;
                TempNode=Node->m_FNode;
            }
            else
            {   //父節點是祖父節點的左節點
                if(TempNode->m_Coordinate==LEFT)
                {
                    //父節點的是紅色叔叔節點是黑色當前節點是右孩子
                    if(Node->m_Coordinate==RIGHT)
                    {
                        LeftRotation(TempNode);
                        Node=TempNode;
                        TempNode=Node->m_FNode;
                    }
                    //父節點的是紅色叔叔節點是黑色當前節點是左孩子
                    else if(Node->m_Coordinate==LEFT)
                    {
                        TempNode->m_Colour=false;
                        TempNode->m_FNode->m_Colour=true;
                        RightRotation(TempNode->m_FNode);
                    }
                }
                else
                {
                    //父節點的是紅色叔叔節點是黑色當前節點是右孩子
                    if(Node->m_Coordinate==RIGHT)
                    {
                        TempNode->m_Colour=false;
                        TempNode->m_FNode->m_Colour=true;
                        LeftRotation(TempNode->m_FNode);
                    }
                    //父節點的是紅色叔叔節點是黑色當前節點是左孩子
                    else if(Node->m_Coordinate==LEFT)
                    {

                        RightRotation(TempNode);
                        Node=TempNode;
                        TempNode=Node->m_FNode;
                    }
                }
            }
            FatherColour=TempNode==NULL?false:TempNode->m_Colour;
        }
       m_RootNode->m_Colour=false;
    }
    return;
}
void CRedBlackTree::RbDeleteFixup(INode*TempNode)
{
  while(TempNode!=m_RootNode&&TempNode->m_Colour==false)
   {

        if(TempNode->m_Coordinate==LEFT)
        {   INode* BrotherNode=TempNode->m_FNode->m_RNode;
            bool BrotherColour=BrotherNode==NULL ?false:BrotherNode->m_Colour;
            bool BrotherLeftColour=true;
            bool BrotherRightColour=true;
            if(BrotherColour)
            {
                BrotherNode->m_Colour=false;
                TempNode->m_FNode->m_Colour=true;
                LeftRotation(TempNode->m_FNode);
                BrotherNode=TempNode->m_FNode->m_RNode;
            }
            if(NULL!=BrotherNode)
            {
                BrotherLeftColour= BrotherNode->m_LNode!=NULL ?BrotherNode->m_LNode->m_Colour:false;
                BrotherRightColour=BrotherNode->m_RNode!=NULL ?BrotherNode->m_RNode->m_Colour:false;
            }
            //兄弟節點爲黑色,兄弟節點的左右孩子都爲黑色
            if(NULL!=BrotherNode&&!BrotherColour&&!BrotherLeftColour&&!BrotherRightColour)
            {
                BrotherNode->m_Colour=true;
                TempNode=TempNode->m_FNode;
            }
            else
            {
                //兄弟節點爲黑色,兄弟節點左孩子紅色,右孩子黑色。
                if(NULL!=BrotherNode&&!BrotherColour&&!BrotherRightColour)
                {   if(BrotherLeftColour)
                       BrotherNode->m_LNode->m_Colour=false;
                    BrotherNode->m_Colour=true;
                    RightRotation(BrotherNode);
                    BrotherNode=TempNode->m_FNode->m_RNode;
                }
                if(NULL!=BrotherNode)
                {
                    BrotherLeftColour= BrotherNode->m_LNode!=NULL ?BrotherNode->m_LNode->m_Colour:false;
                    BrotherRightColour=BrotherNode->m_RNode!=NULL ?BrotherNode->m_RNode->m_Colour:false;
                }
                //兄弟節點爲黑色,右孩子爲紅色
                if(NULL!=BrotherNode&&!BrotherColour)
                {
                    BrotherNode->m_Colour=TempNode->m_FNode->m_Colour;
                    TempNode->m_FNode->m_Colour=false;
                    if(BrotherRightColour)
                       BrotherNode->m_RNode->m_Colour=false;

                    LeftRotation(TempNode->m_FNode);
                    TempNode=m_RootNode;
                }
            }
        }
        else
        {   INode* BrotherNode=TempNode->m_FNode->m_LNode;
            bool BrotherColour=BrotherNode==NULL ?false:BrotherNode->m_Colour;
            bool BrotherLeftColour=true;
            bool BrotherRightColour=true;
            if(BrotherColour)
            {
                BrotherNode->m_Colour=false;
                TempNode->m_FNode->m_Colour=true;
                RightRotation(TempNode->m_FNode);
                BrotherNode=TempNode->m_FNode->m_LNode;
            }
            if(NULL!=BrotherNode)
            {
                BrotherLeftColour= BrotherNode->m_LNode!=NULL ?BrotherNode->m_LNode->m_Colour:false;
                BrotherRightColour=BrotherNode->m_RNode!=NULL ?BrotherNode->m_RNode->m_Colour:false;
            }
            //兄弟節點爲黑色,兄弟節點的左右孩子都爲黑色
            if(NULL!=BrotherNode&&!BrotherColour&&!BrotherLeftColour&&!BrotherRightColour)
            {
                BrotherNode->m_Colour=true;
                TempNode=TempNode->m_FNode;
            }
            else
            {
                //兄弟節點爲黑色,兄弟節點左孩子紅色,右孩子黑色。
                if(NULL!=BrotherNode&&!BrotherColour&&!BrotherLeftColour)
                {   if(BrotherLeftColour)
                       BrotherNode->m_RNode->m_Colour=false;
                    BrotherNode->m_Colour=true;
                    LeftRotation(BrotherNode);
                    BrotherNode=TempNode->m_FNode->m_LNode;
                }
                if(NULL!=BrotherNode)
                {
                    BrotherLeftColour= BrotherNode->m_LNode!=NULL ?BrotherNode->m_LNode->m_Colour:false;
                    BrotherRightColour=BrotherNode->m_RNode!=NULL ?BrotherNode->m_RNode->m_Colour:false;
                }
                //兄弟節點爲黑色,右孩子爲紅色
                if(NULL!=BrotherNode&&!BrotherColour)
                {
                    BrotherNode->m_Colour=TempNode->m_FNode->m_Colour;
                    TempNode->m_FNode->m_Colour=false;
                    if(BrotherLeftColour)
                       BrotherNode->m_LNode->m_Colour=false;

                    RightRotation(TempNode->m_FNode);
                    TempNode=m_RootNode;
                }
            }
        }
   }
   TempNode->m_Colour=false;
}
void CRedBlackTree::LeftRotation(INode*strNode)
{
    if(strNode->m_RNode==NULL) return;
    //記錄當前節點的父節點
    INode *father=strNode->m_FNode;
    //右節點和父節點相連
    strNode->m_RNode->m_FNode=father;
    strNode->m_RNode->m_Coordinate=ROOT;
    if(NULL!=father)
    {
         if(strNode->m_Coordinate==RIGHT)
           father->m_RNode=strNode->m_RNode;
           else
           father->m_LNode=strNode->m_RNode;

         strNode->m_RNode->m_Coordinate=strNode->m_Coordinate;
    }
    //記錄當前節點的右節點的左節點
    INode * Left=strNode->m_RNode->m_LNode;
    //當前與右節點相連
    strNode->m_FNode=strNode->m_RNode;
    strNode->m_RNode->m_LNode=strNode;
    strNode->m_Coordinate=LEFT;
    //當前節點與右節點的左節點相連
    strNode->m_RNode=Left;
    if(NULL!=Left)
    {
        Left->m_FNode=strNode;
        Left->m_Coordinate=RIGHT;
    }
    //如果當前節點是根節點則更新根節點記錄
    if(strNode->m_FNode->m_Coordinate==ROOT)
        m_RootNode=strNode->m_FNode;
    return;
}
void CRedBlackTree::RightRotation(INode*strNode)
{
//當前節點沒有左節點不能右旋轉
    if(NULL==strNode->m_LNode) return ;
    //記錄當前節點的祖父節點
    INode *father=strNode->m_FNode;
    //記錄當前節點的左節點
    INode *m_LNode=strNode->m_LNode;
    //當前節點的左節點與當前節點的父節點連接
    m_LNode->m_FNode=father;
    m_LNode->m_Coordinate=ROOT;
    if(NULL!=father)
    {    if(strNode->m_Coordinate==LEFT)
           father->m_LNode=m_LNode;
         else
           father->m_RNode=m_LNode;
         m_LNode->m_Coordinate=strNode->m_Coordinate;
    }
    //記錄當前節點的左節點的右節點
    INode * Right=strNode->m_LNode->m_RNode;
    //當前節點與左節點連接
    m_LNode->m_RNode=strNode;
    strNode->m_FNode=m_LNode;
    strNode->m_Coordinate=RIGHT;
    //當前節點的左節點與當前節點的左節點的右節點連接
    strNode->m_LNode=Right;
    if(NULL!=Right)
      {
          Right->m_FNode=strNode;
          Right->m_Coordinate=LEFT;
      }
    //如果當前節點是根節點則更新根節點記錄
    if(strNode->m_FNode->m_Coordinate==ROOT)
        m_RootNode=strNode->m_FNode;
    return;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章