算法导论红黑树的C++实现

来源:互联网 发布:sql 表别名 编辑:程序博客网 时间:2024/06/06 02:28
按照算法导论里的红黑树伪代码用C++实现了一下,并附带一些测试代码。#include <iostream>#include <utility>using namespace std;enum Color{RED,BLACK};//颜色标记template<class T>class Binary_Tree_Node//红黑树节点{public:Binary_Tree_Node(){parent=NULL;leftchild=NULL;rightchild=NULL;C=BLACK;}Binary_Tree_Node<T> * parent;//*/父节点*/Binary_Tree_Node<T> * leftchild;//左子树Binary_Tree_Node<T> * rightchild;//后子树T Key;//键值Color C;//颜色标记};template<class T>class Binary_Tree//红黑树结构{public:Binary_Tree(){root =NULL;}Binary_Tree_Node<T> * root;//根节点};template<class T>void Inorder_Tree_Walk( Binary_Tree_Node<T> * A)//顺序打印树{if (A!=NULL){Inorder_Tree_Walk(A->leftchild);cout<<A->Key<<"  ";Inorder_Tree_Walk(A->rightchild);}}template<class T>Binary_Tree_Node<T> * Tree_Search( Binary_Tree_Node<T> * A,const T & Search_Key)//递归查找{if (A==NULL||A->Key==Search_Key){return A;}if (A->Key<Search_Key){return Tree_Search(A->rightchild,Search_Key);}else{return Tree_Search(A->leftchild,Search_Key);}}template<class T>Binary_Tree_Node<T> * Interative_Tree_Search( Binary_Tree_Node<T> * A,const T   & Search_Key )//非递归查找{Binary_Tree_Node<T> * temp=A;while(temp!=NULL&& temp->Key!=Search_Key){if (temp->Key<Search_Key){temp=temp->leftchild;}else{temp=temp->rightchild;}}return temp;}template<class T>Binary_Tree_Node<T> * Tree_Min(Binary_Tree_Node<T> * A)//求节点下的最小值{Binary_Tree_Node<T> * temp=A;Binary_Tree_Node<T> * tempRt=NULL;while (temp!=NULL){tempRt=temp;temp=temp->leftchild;}return tempRt;}template<class T>Binary_Tree_Node<T> * Tree_Max(Binary_Tree_Node<T> * B)//求节点下的最大值{Binary_Tree_Node<T> * temp=B;Binary_Tree_Node<T> * tempRt=NULL;while(temp!=NULL){tempRt=temp;temp=temp->rightchild;}return tempRt;}template<class T>Binary_Tree_Node<T> * Successor(Binary_Tree_Node<T> * A)//求比节点的大的后一个值{Binary_Tree_Node<T> * temp=A;if (temp!=NULL){if (temp->rightchild!=NULL){return Tree_Min(temp->rightchild);}Binary_Tree_Node<T> * y=temp->parent;while(y!=NULL && temp==y->rightchild){temp=y;y=y->parent;}return y;}else{return temp;}}template<class T> Binary_Tree_Node<T> * Predecessor(Binary_Tree_Node<T> * A)//求比节点小的前一个值{Binary_Tree_Node<T> * temp=A;if (temp!=NULL){if (temp->leftchild!=NULL){return Tree_Max(temp->leftchild);}Binary_Tree_Node<T> * y=temp->parent;while(y!=NULL && temp==y->leftchild){temp=y;y=y->parent;}return y;}else{return temp;}}template<class T>void RB_Tree_Insert(Binary_Tree<T> & Tree,const T & InsertKey)//红黑树插入{Binary_Tree_Node<T> * y=NULL;Binary_Tree_Node<T> * x=Tree.root;while(x!=NULL){y=x;if (x->Key<InsertKey){x=x->rightchild;}else{x=x->leftchild;}}Binary_Tree_Node<T> * NewNode=new Binary_Tree_Node<T>;NewNode->Key=InsertKey;NewNode->parent=y;if (y==NULL){Tree.root=NewNode;}else{if (y->Key<InsertKey){y->rightchild=NewNode;}else{y->leftchild=NewNode;}}NewNode->C=RED;RB_Tree_Insert_Fixup(Tree,NewNode);//插入后修复红黑树属性}template<class T>void RB_Tree_Insert_Fixup(Binary_Tree<T> & Tree,Binary_Tree_Node<T> * NewNode){Binary_Tree_Node<T> * Z=NULL;/*Binary_Tree_Node<T> Nil;*/Z=NewNode;while(Z->parent!=NULL&&Z->parent->C==RED){Binary_Tree_Node<T> * y=NULL;if (Z->parent==Z->parent->parent->leftchild){y=Z->parent->parent->rightchild;if (y!=NULL&&y->C==RED){y->C=BLACK;Z->parent->C=BLACK;Z->parent->parent->C=RED;Z=Z->parent->parent;continue;}else{if (Z==Z->parent->rightchild){Z=Z->parent;Left_Roation(Tree,Z);continue;}else{Z->parent->C=BLACK;Z->parent->parent->C=RED;Right_Roation(Tree,Z->parent->parent);}}}else {y=Z->parent->parent->leftchild;if (y!=NULL&&y->C==RED){y->C=BLACK;Z->parent->C=BLACK;Z->parent->parent->C=RED;Z=Z->parent->parent;continue;}else{if (Z==Z->parent->leftchild){Z=Z->parent;Right_Roation(Tree,Z);continue;}else{Z->parent->C=BLACK;Z->parent->parent->C=RED;Left_Roation(Tree,Z->parent->parent);}}}}Tree.root->C=BLACK;}template<class T>void Tree_Insert(Binary_Tree<T> & Tree,const T & InsertKey)//普通二叉树插入{Binary_Tree_Node<T> * y=NULL;Binary_Tree_Node<T> * x=Tree.root;while(x!=NULL){y=x;if (x->Key<InsertKey){x=x->rightchild;}else{x=x->leftchild;}}Binary_Tree_Node<T> * NewNode=new Binary_Tree_Node<T>;NewNode->Key=InsertKey;NewNode->parent=y;if (y==NULL){Tree.root=NewNode;}else{if (y->Key<InsertKey){y->rightchild=NewNode;}else{y->leftchild=NewNode;}}return ;}template<class T>void RB_Tree_Delete(Binary_Tree<T> & Tree,Binary_Tree_Node<T> * DeleteNode)//红黑树删除{Binary_Tree_Node<T> * tempDeleteNode=DeleteNode;Binary_Tree_Node<T> * y=NULL;Binary_Tree_Node<T> * x=NULL;Binary_Tree_Node<T> Nil;//本地临时的Nilif (tempDeleteNode!=NULL){if (tempDeleteNode->leftchild==NULL||tempDeleteNode->rightchild==NULL){y=tempDeleteNode;}else{y=Successor(tempDeleteNode);}if (y->leftchild!=NULL){x=y->leftchild;}else{x=y->rightchild;}if (x==NULL){x=&Nil;//x为null 则赋值为nil的指针;.}x->parent=y->parent;if (y->parent==NULL){Tree.root=x;}else if (y==y->parent->leftchild){y->parent->leftchild=x;}else{y->parent->rightchild=x;}if (y!=DeleteNode){DeleteNode->Key=y->Key;}if (y->C==BLACK){RB_Tree_Delete_FixUp(Tree,x);//修复红黑树属性}if (Nil.parent!=NULL)//将临时插入的nil还原为null指针{if (&Nil==Nil.parent->leftchild){Nil.parent->leftchild=NULL;}else if (&Nil==Nil.parent->rightchild){Nil.parent->rightchild=NULL;}}if (Tree.root==&Nil){Tree.root=NULL;}delete y;return;}else{return ;}}template<class T>void RB_Tree_Delete_FixUp(Binary_Tree<T> & Tree,Binary_Tree_Node<T> * x){while(x!=Tree.root&&x->C==BLACK){Binary_Tree_Node<T> * w=NULL;if (x==x->parent->leftchild){w=x->parent->rightchild;if (w!=NULL&&w->C==RED){w->C=BLACK;x->parent->C=RED;Left_Roation(Tree,x->parent);w=x->parent->rightchild;}if (w==NULL||(w!=NULL&&(w->leftchild==NULL||w->leftchild->C==BLACK)&&(w->rightchild==NULL||w->rightchild->C==BLACK))){if (w!=NULL){w->C=RED;}x=x->parent;continue;}else if(w->rightchild==NULL||w->rightchild->C==BLACK){w->C=RED;w->leftchild->C=BLACK;Right_Roation(Tree,w);w=x->parent->rightchild;}w->C=x->parent->C;x->parent->C=BLACK;w->rightchild->C=BLACK;Left_Roation(Tree,x->parent);x=Tree.root;}else{w=x->parent->leftchild;if (w!=NULL&&w->C==RED){w->C=BLACK;x->parent->C=RED;Right_Roation(Tree,x->parent);w=x->parent->leftchild;}if (w==NULL||(w!=NULL&&(w->leftchild==NULL||w->leftchild->C==BLACK)&&(w->rightchild==NULL||w->rightchild->C==BLACK))){if (w!=NULL){w->C=RED;}x=x->parent;continue;}else if (w->leftchild==NULL||w->leftchild->C==BLACK){w->C=RED;w->rightchild->C=BLACK;Left_Roation(Tree,w);w=x->parent->leftchild;}w->C=x->parent->C;x->parent->C=BLACK;w->leftchild->C=BLACK;Right_Roation(Tree,x->parent);x=Tree.root;}}x->C=BLACK;return;}template<class T>void Tree_Delete(Binary_Tree<T> & Tree,Binary_Tree_Node<T> * DeleteNode)//普通二叉树删除{Binary_Tree_Node<T> * tempDeleteNode=DeleteNode;Binary_Tree_Node<T> * y=NULL;Binary_Tree_Node<T> * x=NULL;if (tempDeleteNode!=NULL){if (tempDeleteNode->leftchild==NULL||tempDeleteNode->rightchild==NULL){y=tempDeleteNode;}else{y=Successor(tempDeleteNode);}if (y->leftchild!=NULL){x=y->leftchild;}else{x=y->rightchild;}if (x!=NULL){x->parent=y->parent;}if (y->parent==NULL){Tree.root=x;}else if (y==y->parent->leftchild){y->parent->leftchild=x;}else{y->parent->rightchild=x;}if (y!=DeleteNode){DeleteNode->Key=y->Key;}delete y;return;}else{return ;}}template<class T>void Left_Roation(Binary_Tree<T> & Tree,Binary_Tree_Node<T> * Node)//左旋{Binary_Tree_Node<T> * y=NULL;y=Node->rightchild;if (y!=NULL){if (y->leftchild!=NULL){Node->rightchild=y->leftchild;y->leftchild->parent=Node;}else{Node->rightchild=NULL;}y->parent=Node->parent;if (Node->parent==NULL){Tree.root=y;}else{if (Node->parent->leftchild==Node){Node->parent->leftchild=y;}else{Node->parent->rightchild=y;}}y->leftchild=Node;Node->parent=y;}return;}template<class T>void Right_Roation(Binary_Tree<T> & Tree,Binary_Tree_Node<T> * Node)//右旋{Binary_Tree_Node<T> * y=NULL;y=Node->leftchild;if (y!=NULL){if (y->rightchild!=NULL){Node->leftchild=y->rightchild;y->rightchild->parent=Node;}else{Node->leftchild=NULL;}y->parent=Node->parent;if (Node->parent==NULL){Tree.root=y;}else{if (Node->parent->leftchild==Node){Node->parent->leftchild=y;}else{Node->parent->rightchild=y;}}y->rightchild=Node;Node->parent=y;}return;}#include <algorithm>int * randIntGernate(int Num,bool output=true)//生成随机测试数组{if (Num<=0){return NULL;}int * RT=new int[Num];for (int i=0;i<Num;i++){RT[i]=i;}random_shuffle(RT,RT+Num);//if (output){cout<<"gernate rand "<<Num<<" Int array:"<<endl;for (int i=0;i<Num;i++){cout<<RT[i]<<" ";}cout<<endl;}//return RT;}#include <utility>typedef pair<int,int> count_Pair;template<class T>void count_Path_Color(Binary_Tree_Node<T> * Node,count_Pair PathCount=count_Pair(0,0))//打印红黑树的节点分布情况,检测红黑树是否正确{if (Node!=NULL){if (Node->C==RED){PathCount.first++;}else{PathCount.second++;}count_Path_Color(Node->leftchild,PathCount);count_Path_Color(Node->rightchild,PathCount);}else{PathCount.second++;cout<<"RED:  "<<PathCount.first<<"  BLACK:  "<<PathCount.second<<endl;}}#include <string>template<class T> void Print_Tree(Binary_Tree_Node<T> * Node, string s ="")//递归打印一颗树{cout<<s;if (Node!=NULL){if (Node->leftchild==NULL&&Node->rightchild==NULL){cout<<Node->Key<<"_"<<(Node->C==RED?'R':'B')<<endl;//leafreturn;}cout<<Node->Key<<"_"<<(Node->C==RED?'R':'B')<<" :[";Inorder_Tree_Walk(Node);cout<<"]"<<endl;//Print_Tree(Node->leftchild,s+"|  ");Print_Tree(Node->rightchild,s+"   ");}else{cout<<"NULL_B\r\n";}}void doTest(bool output=true)//测试{while(1){cout<<"How many nodes do you want the RB_Tree to have"<<endl;int num;cin>>num;int * arrayInt=randIntGernate(num,output);//随机化一个数组,填充红黑树Binary_Tree<int> tttt;for (int i=0;i<num;i++){RB_Tree_Insert(tttt,arrayInt[i]);}delete [] arrayInt;Print_Tree(tttt.root);cout<<endl;count_Path_Color(tttt.root);while(1){cout<<"Please chose an operator \r\n0:search\r\n1:delete\r\n2:insert\r\n-1:new RB_Tree\r\n";int a;cin>>a;if (a==-1)//新的树{break;}if (a==0)//查询{cout<<"please input the number to be searched:"<<endl;int number;cin>>number;Binary_Tree_Node<int> * find=Tree_Search(tttt.root,number);if (find!=NULL){cout<<"find "<<number<<endl;}else{cout<<"can not find "<<number<<endl;}}if (a==1)//删除{cout<<"please input the number to be deleted:"<<endl;int number;cin>>number;Binary_Tree_Node<int> * find=Tree_Search(tttt.root,number);if (find==NULL){cout<<number<<" not exist"<<endl;}cout<<"before delete"<<endl;Print_Tree(tttt.root);cout<<endl;count_Path_Color(tttt.root);cout<<endl;RB_Tree_Delete(tttt,find);cout<<"after delete "<<endl;Print_Tree(tttt.root);cout<<endl;count_Path_Color(tttt.root);cout<<endl;}else if (a==2)//插入{cout<<endl;cout<<"Please input the number to be inserted:"<<endl;int Num;cin>>Num;cout<<"before insert "<<endl;Print_Tree(tttt.root);cout<<endl;count_Path_Color(tttt.root);cout<<endl;RB_Tree_Insert(tttt,Num);cout<<"after insert:"<<Num<<endl;Print_Tree(tttt.root);cout<<endl;count_Path_Color(tttt.root);cout<<endl;}}}}


原创粉丝点击