2013-3-19 23:02 完成红黑树的插入操作,红黑树的搜索与搜索二叉树的搜索函数是相同的。每天抽点时间看书。
//BLTreePractise.cpp
#include "BlackRedTree.h"
void main()
{
BlackRedTree<int> Bl;
int a[] = {1,2,3,9,5,4,10,6,8,7};
for(int i= 0;i<sizeof(a)/sizeof(int);i++)
{
//cout<<"a[i]:"<<a[i]<<endl;
cout<<"===================="<<endl;
Bl.Insert(a[i]);
Bl.PrintTree();
}
return;
}
//BlackRedTree.h
#ifndef __BLACK_RED_TREE
#define __BLACK_RED_TREE
#include <iostream>
using namespace std;
#define RED 1
#define BLACK 0
#define OutMsg(FunName) (cout<<FunName<<endl)
template<class T> class BlackTree;
template<class T> class BlackRedNode
{
public:
template<class T> friend class BlackRedTree;
BlackRedNode():Color(BLACK),Left(NULL),Right(NULL),Parent(NULL){;}
BlackRedNode(const T& e,int NodeColor=BLACK,BlackRedNode<T>* LeftNode=NULL,BlackRedNode<T>* RightNode=NULL,BlackRedNode<T>* ParentNode=NULL):Data(e),Color(NodeColor),Left(LeftNode),Right(RightNode),Parent(ParentNode){;}
private:
T Data;
int Color;//0:black,1:red
BlackRedNode<T>* Left,*Right;
BlackRedNode<T>* Parent;
};
template<class T> class BlackRedTree
{
public:
BlackRedTree():Root(NULL){;}
BlackRedTree(const T& x);
BlackRedTree<T>& Insert(const T& e);
bool AdjustColorAfterInsert(BlackRedNode<T>* Node); //Node为新插入节点的指针。插入节点之后,判断是否违反RB2,如果违反则进行调整
//XYr类型,调整之后,可能还需要继续调整
bool LXr_AfterInsert(BlackRedNode<T>* Node);//插入之后,如果为LXr形式,则进行相应调整,其他与此类似,Node为插入的元素指针。X为L或者R
bool RXr_AfterInsert(BlackRedNode<T>* Node);//插入之后为RXr类型:X为R或者L;
//XYb类型,调整之后不再需要继续调整
bool LLb_AfterInsert(BlackRedNode<T>* Node);
bool LRb_AfterInsert(BlackRedNode<T>* Node);
bool RRb_AfterInsert(BlackRedNode<T>* Node);
bool RLb_AfterInsert(BlackRedNode<T>* Node);
void PrintTree() const{PrintTree(Root,0);}//打印红黑树
private:
void PrintTree(BlackRedNode<T>* Node,int Layer)const;
BlackRedNode<T>* Root;
};
template<class T> BlackRedTree<T>::BlackRedTree(const T& x)
{
Root = new BlackRedNode<T>(x);
}
template<class T> BlackRedTree<T>& BlackRedTree<T>::Insert(const T& e)
{
if(!Root)
{
Root = new BlackRedNode<T>(e);
return *this;
}
BlackRedNode<T>* Temp,*pTemp;
int InsertDirection = 0;//0:左,1:右
Temp = Root;
while(Temp)
{
pTemp = Temp;
if(e > Temp->Data)
{
Temp = Temp->Right;
InsertDirection = 1;
}
else
{
Temp = Temp->Left;
InsertDirection = 0;
}
if(Temp)
{
Temp->Parent = pTemp;
}
}
//这里的temp即为要插入的位置
Temp = new BlackRedNode<T>(e,RED);
Temp->Parent = pTemp;
if(InsertDirection)
{
pTemp->Right = Temp;
}
else
{
pTemp->Left = Temp;
}
//接下来调整颜色
AdjustColorAfterInsert(Temp);
return *this;
}
template<class T> bool BlackRedTree<T>::AdjustColorAfterInsert(BlackRedNode<T>* Node)
{
BlackRedNode<T>* PNode,*GNode;
if(Node == Root)
{
Root->Color = BLACK;
return true;
}
PNode = Node->Parent;
if(PNode->Color == BLACK)
{
cout<<"PNode->Color == BLACK,这时候不需要调整颜色"<<endl;
return true;
}
//既然PNode是红色的,那么一定有GNode存在,而且GNode一定是黑色的
GNode = PNode->Parent;
//一共有8种情况:LLr,LRr,RRr,RLr,LLb,LRb,RRb,RLb.(这种情况包括gu的另一个孩子是外部节点的情况)
if(PNode == GNode->Left && (GNode->Right!=NULL && GNode->Right->Color == RED))//LXr
{
LXr_AfterInsert(Node);
return AdjustColorAfterInsert(GNode);
}
if(PNode == GNode->Right && (GNode->Left!=NULL && GNode->Left->Color == RED))//RXr
{
RXr_AfterInsert(Node);
return AdjustColorAfterInsert(GNode);
}
if(PNode == GNode->Left && Node == PNode->Left && (GNode->Right ==NULL || (GNode->Right!=NULL && GNode->Right->Color == BLACK) ))//LLb
{
return LLb_AfterInsert(Node);
}
if(PNode == GNode->Left && Node == PNode->Right && (GNode->Right ==NULL || (GNode->Right!=NULL && GNode->Right->Color == BLACK) ))//LRb
{
return LRb_AfterInsert(Node);
}
if(PNode == GNode->Right && Node == PNode->Right && (GNode->Left == NULL || (GNode->Left!=NULL && GNode->Left->Color == BLACK)))//RRb
{
return RRb_AfterInsert(Node);
}
if(PNode == GNode->Right && Node == PNode->Left && (GNode->Left == NULL || (GNode->Left!=NULL && GNode->Left->Color == BLACK)))//RLb
{
return RLb_AfterInsert(Node);
}
}
template<class T> bool BlackRedTree<T>::LXr_AfterInsert(BlackRedNode<T>* Node)
{
OutMsg("LXr_AfterInsert");
BlackRedNode<T>* PNode,*GNode;
PNode = Node->Parent;
GNode = PNode->Parent;
if( PNode!= GNode->Left || GNode->Right == NULL || (GNode->Right!=NULL && GNode->Right->Color!=RED) )
{
cout<<"插入节点之后,不是LXr类型"<<endl;
return true;
}
//根据数据结构上给出的算法进行颜色调整
GNode->Color = RED;
PNode->Color = BLACK;
GNode->Right->Color = BLACK;
//这样调整完之后,可能还存在违反RB2,这个交给AdjustColorAfterInsert函数来处理
return true;
}
template<class T> bool BlackRedTree<T>::RXr_AfterInsert(BlackRedNode<T>* Node)
{
OutMsg("RXr_AfterInsert");
BlackRedNode<T>* PNode,*GNode;
PNode = Node->Parent;
GNode = PNode->Parent;
if(PNode!= GNode->Right || (GNode->Left!=NULL && GNode->Left->Color!=RED))
{
cout<<"插入节点之后,不是RXr类型"<<endl;
return true;
}
//根据数据结构上给出的算法进行颜色调整
GNode->Color = RED;
PNode->Color = BLACK;
GNode->Left->Color = BLACK;
//这样调整完之后,可能还存在违反RB2,这个交给AdjustColorAfterInsert函数来处理
return true;
}
template<class T> bool BlackRedTree<T>::LLb_AfterInsert(BlackRedNode<T>* Node)
{
OutMsg("LLb_AfterInsert");
BlackRedNode<T>* PNode,*GNode;
PNode = Node->Parent;
GNode = PNode->Parent;
if(PNode!= GNode->Left || Node!= PNode->Left || (GNode->Right!=NULL && GNode->Right->Color!=BLACK))
{
cout<<"插入节点之后,不是LLb类型"<<endl;
return true;
}
//根据数据结构上给出的算法进行旋转
BlackRedNode<T>* NewNode,*NodeToDelete;
NewNode = new BlackRedNode<T>(GNode->Data,RED);
NodeToDelete = GNode->Left;
NewNode->Left = NodeToDelete->Right;
NewNode->Right = GNode->Right;
GNode->Left = NodeToDelete->Left;
GNode->Right = NewNode;
GNode->Data = NodeToDelete->Data;
//调整父节点
if(NewNode)
{
NewNode->Parent = GNode;
if(NewNode->Left)
{
NewNode->Left->Parent = NewNode;
}
if(NewNode->Right)
{
NewNode->Right->Parent = NewNode;
}
}
if(GNode->Left)
{
GNode->Left->Parent = GNode;
}
if(GNode->Right)
{
GNode->Right->Parent = GNode;
}
//删除节点
if(!NodeToDelete)
{
delete NodeToDelete;
NodeToDelete = NULL;
}
return true;
}
template<class T> bool BlackRedTree<T>::LRb_AfterInsert(BlackRedNode<T>* Node)
{
OutMsg("LRb_AfterInsert");
BlackRedNode<T>* PNode,*GNode;
PNode = Node->Parent;
GNode = PNode->Parent;
if(PNode!= GNode->Left || Node!= PNode->Right || (GNode->Right!=NULL && GNode->Right->Color!=BLACK))
{
cout<<"插入节点之后,不是LRb类型"<<endl;
return true;
}
//根据数据结构上给出的算法进行旋转
BlackRedNode<T>* NewNode,*NodeToDelete;
NewNode = new BlackRedNode<T>(GNode->Data,RED);
NodeToDelete = PNode ->Right;
NewNode->Left = NodeToDelete->Right;
NewNode->Right = GNode->Right;
GNode->Left->Right = NodeToDelete->Left;
GNode->Right = NewNode;
GNode->Data = NodeToDelete->Data;
PNode->Right = NodeToDelete ->Left;
//调整父节点
if(NewNode)
{
if(NewNode->Left)
{
NewNode->Left->Parent = NewNode;
}
if(NewNode->Right)
{
NewNode->Right->Parent = NewNode;
}
}
if(GNode->Left->Right)
{
GNode->Left->Right->Parent = GNode;
}
if(GNode->Right)
{
GNode->Right->Parent = GNode;
}
if(PNode->Right)
{
PNode->Right->Parent = PNode;
}
//删除节点
if(!NodeToDelete)
{
delete NodeToDelete;
NodeToDelete = 0;
}
return true;
}
template<class T> bool BlackRedTree<T>::RRb_AfterInsert(BlackRedNode<T>* Node)
{
OutMsg("RRb_AfterInsert");
BlackRedNode<T>* PNode,*GNode;
PNode = Node->Parent;
GNode = PNode->Parent;
if(PNode!= GNode->Right || Node!= PNode->Right || (GNode->Left!=NULL && GNode->Left->Color!=BLACK))
{
cout<<"插入节点之后,不是RRb类型"<<endl;
return true;
}
//进行旋转
BlackRedNode<T>* NewNode,*NodeToDelete;
NewNode = new BlackRedNode<T>(GNode->Data,RED);
NodeToDelete = PNode;
NewNode->Left = GNode->Left;
NewNode->Right = NodeToDelete->Left;
GNode->Data = NodeToDelete->Data;
GNode->Left = NewNode;
GNode->Right = NodeToDelete->Right;
//调整父节点
if(NewNode)
{
if(NewNode->Left)
{
NewNode->Left->Parent = NewNode;
}
if(NewNode->Right)
{
NewNode->Right->Parent = NewNode;
}
}
if(GNode->Left)
{
GNode->Left->Parent = GNode;
}
if(GNode->Right)
{
GNode->Right->Parent = GNode;
}
//删除节点
if(!NodeToDelete)
{
delete NodeToDelete;
NodeToDelete = 0;
}
return true;
}
template<class T> bool BlackRedTree<T>::RLb_AfterInsert(BlackRedNode<T>* Node)
{
OutMsg("RLb_AfterInsert");
BlackRedNode<T>* PNode,*GNode;
PNode = Node->Parent;
GNode = PNode->Parent;
if(PNode!= GNode->Right || Node!= PNode->Left || (GNode->Left!=NULL && GNode->Left->Color!=BLACK))
{
cout<<"插入节点之后,不是RLb类型"<<endl;
return true;
}
//进行旋转
BlackRedNode<T>* NewNode,*NodeToDelete;
NewNode = new BlackRedNode<T>(GNode->Data,RED);
NodeToDelete = PNode->Left;
NewNode->Left = GNode->Left;
NewNode->Right = NodeToDelete->Left;
GNode->Data = NodeToDelete->Data;
GNode->Left = NewNode;
GNode->Right->Left = NodeToDelete->Right;
//调整父节点
if(NewNode)
{
if(NewNode->Left)
{
NewNode->Left->Parent = NewNode;
}
if(NewNode->Right)
{
NewNode->Right->Parent = NewNode;
}
}
if(GNode->Left)
{
GNode->Left->Parent = GNode;
}
if(GNode->Right->Left)
{
GNode->Right->Left->Parent = GNode;
}
//删除节点
if(!NodeToDelete)
{
delete NodeToDelete;
NodeToDelete = 0;
}
return true;
}
template <class T> void BlackRedTree<T>::PrintTree(BlackRedNode<T> *t,int layer) const{
if(t == NULL ) return;
if(t->Right) PrintTree(t->Right,layer+1);
for(int i =0;i<layer;i++) cout<<" ";
cout<<t->Data<<":"<<t->Color<<endl;
if(t->Left) PrintTree(t->Left,layer+1);
}
#endif