红黑树代码

来源:互联网 发布:编程笔记本配置要求 编辑:程序博客网 时间:2024/06/16 01:49
#include<iostream>#include<vector>#include<algorithm>#include<sstream>using namespace std;//enum color_type{black,red};template<typename T>class rb_tree{enum color_type{black,red};struct rbtree{rbtree(){p=left=right=NULL;}T key;rbtree *p;//父节点rbtree *left;rbtree *right;color_type color;//节点颜色};void left_rotate(rbtree *p);void right_rotate(rbtree *p);void dleftrotate(rbtree *p);void drightrotate(rbtree *p);void copy(rbtree *&root,rbtree *&oth);void pre(rbtree *root);void in(rbtree *root);void post(rbtree *root);void xiao(rbtree *root);void treemin(rbtree **ptr);//有时间写返回的函数void insert_fixup(rbtree *ptr);void rb_de_node(rbtree **ptr,rbtree **rb);void rb_deletefixup(rbtree *ptr);int height(rbtree *root){if(root==NULL)return 0;return 1+max(height(root->left),height(root->right));}private:rbtree *root;bool flag;public:rb_tree();~rb_tree();rb_tree(const rb_tree<T> &oth);const rb_tree<T> &operator=(const rb_tree<T> *&);void porder();void order();void afterorder();int max(T a,T b){return a>b?a:b;}int treeheight(){   return height(root);}bool empty(){return root==NULL;}void insert(T value);bool find(T n);rbtree *findn(T n){rbtree *temp=root;while(temp){if(temp->key<n)temp=temp->right;else if(temp->key==n)return temp;elsetemp=temp->left;}return NULL;}void delen(T n);};template<typename T>rb_tree<T>::rb_tree(){root=new rbtree();root->color=black;flag=true;//root=NULL;}template<typename T>rb_tree<T>::~rb_tree(){     xiao(root);}template<typename T>rb_tree<T>::rb_tree(const rb_tree<T> &oth){if(oth==NULL)root=NULL;elsecopy(root,oth);}template<typename T>void rb_tree<T>::copy(rbtree *&root, rbtree *&oth){if(oth==NULL)root=NULL;else{root=new rbtree();root->color=oth->color;root->key=oth->key;copy(root->left,oth->left);copy(root->right,oth->right);}}template<typename T>const rb_tree<T> &rb_tree<T>::operator =(const rb_tree<T> *&ot){if(ot!=this){if(root!=NULL)xiao(root);if(ot==NULL)root=NULL;elsecopy(root,ot);}return *this;}template<typename T>void rb_tree<T>::xiao(rbtree *root){//rbtree *p=root;if(root==NULL)return;else{xiao(root->left);xiao(root->right);delete root;root=NULL;}}template<typename T>void rb_tree<T>::porder(){pre(root);}template<typename T>void rb_tree<T>::pre(rbtree *root){if(root!=NULL){cout<<root->key;pre(root->left);pre(root->right);}}template<typename T>void rb_tree<T>::order(){in(root);}template<typename T>void rb_tree<T>::in(rbtree *root){if(root!=NULL){in(root->left);cout<<root->key;in(root->right);}}template<typename T>void rb_tree<T>::afterorder(){post(root);}template<typename T>void rb_tree<T>::post(rbtree *root){if(root!=NULL){post(root->left);post(root->right);cout<<root->key;}}template<typename T>void rb_tree<T>::left_rotate(rbtree *ptr){rbtree *temp=ptr->right;ptr->right=temp->left;// turn temp subtree into ptr subtreeif(temp->left!=NULL)temp->left->p=ptr;temp->p=ptr->p;//link ptr parent to tempif(ptr->p==NULL)root=temp;else if(ptr==ptr->p->left)ptr->p->left=temp;else ptr->p->right=temp;temp->left=ptr;ptr->p=temp;}template<typename T>void rb_tree<T>::right_rotate(rbtree *ptr){rbtree *temp=ptr->left;ptr->left=temp->right;if(temp->right!=NULL)temp->right->p=ptr;temp->p=ptr->p;if(ptr->p==NULL)root=temp;else if(ptr==ptr->p->left)ptr->p->left=temp;elseptr->p->right=temp;temp->right=ptr;ptr->p=temp;}//--------------------------插入结点总操作----------------------------------              //全部的工作,都在下述伪代码中:              /*RB-INSERT(T, z)                1  y ← nil[T]                 // y 始终指向 x 的父结点。             2  x ← root[T]              // x 指向当前树的根结点,             3  while x ≠ nil[T]             4      do y ← x             5         if key[z] < key[x]           //向左,向右..             6            then x ← left[x]             7            else x ← right[x]   //为了找到合适的插入点,x探路跟踪路径,直到x成为NIL 为止。             8  p[z] ← y         //y置为 插入结点z 的父结点。             9  if y = nil[T]             10     then root[T] ← z             11     else if key[z] < key[y]             12             then left[y] ← z             13             else right[y] ← z     //此 8-13行,置z 相关的指针。             14  left[z] ← nil[T]             15  right[z] ← nil[T]            //设为空,             16  color[z] ← RED             //将新插入的结点z作为红色             17  RB-INSERT-FIXUP(T, z)                */              //因为将z着为红色,可能会违反某一红黑性质,              //所以需要调用下面的RB-INSERT-FIXUP(T, z)来保持红黑性质。  template<typename T>void rb_tree<T>::insert(T value){rbtree *node=new rbtree();node->color=red;node->key=value;rbtree *temp=root;rbtree *cur;if(root==NULL||flag){root=node;flag=false;}else{while(temp!=NULL){cur=temp;if(temp->key<value)temp=temp->right;else if(temp->key>value)temp=temp->left;else{cerr<<"in tree";return ;}}if(cur->key<value)cur->right=node;elsecur->left=node;node->p=cur;//与搜索二叉树的区别在于加父节点}insert_fixup(node);//调整} //---------------------插入结点性质修复--------------------------------              //3种插入情况,都在下面的伪代码中(未涉及到所有全部的插入情况)。              /*             RB-INSERT-FIXUP(T, z)             1 while color[p[z]] = RED             2     do if p[z] = left[p[p[z]]]             3           then y ← right[p[p[z]]]             4                if color[y] = RED             5                   then color[p[z]] ← BLACK                    ? Case 1             6                        color[y] ← BLACK                       ? Case 1             7                        color[p[p[z]]] ← RED                   ? Case 1             8                        z ← p[p[z]]                            ? Case 1             9                   else if z = right[p[z]]             10                           then z ← p[z]                       ? Case 2             11                                LEFT-ROTATE(T, z)              ? Case 2             12                           color[p[z]] ← BLACK                 ? Case 3             13                           color[p[p[z]]] ← RED                ? Case 3             14                           RIGHT-ROTATE(T, p[p[z]])            ? Case 3             15           else (same as then clause with "right" and "left" exchanged)             16 color[root[T]] ← BLACK             */  template<typename T>void rb_tree<T>::insert_fixup(rbtree *ptr){rbtree *uncle;while(ptr!=root&&ptr->p->color==red){if(ptr->p==ptr->p->p->left){uncle=ptr->p->p->right;if(uncle&&uncle->color==red)////插入情况1,z的叔叔y是红色的。{ptr->p->color=black;uncle->color=black;ptr->p->p->color=red;ptr=ptr->p->p;}else {  if(ptr==ptr->p->right)//插入情况2:z的叔叔y是黑色的。{ptr=ptr->p;left_rotate(ptr);}ptr->p->color=black;  //插入情况3:z的叔叔y是黑色的,但z是左孩子。ptr->p->p->color=red;right_rotate(ptr->p->p);}}else{uncle=ptr->p->p->left;if(uncle&&uncle->color==red){ptr->p->color=black;//更改节点为黑uncle->color=black;ptr->p->p->color=red;ptr=ptr->p->p;}else{if(ptr==ptr->p->left){ptr=ptr->p;right_rotate(ptr);}ptr->p->color=black;  //插入情况3:z的叔叔y是黑色的,但z是左孩子。ptr->p->p->color=red;left_rotate(ptr->p->p);}}}root->color=black;//根必须是黑}template<typename T>bool rb_tree<T>::find(T n){rbtree *temp;temp=findn(n);if(temp==NULL)return false;return true;}/*template<typename T>rbtree *rb_tree<T>::findn(T n){rbtree *temp=root;while(temp){if(temp->key<n)temp=temp->right;else if(temp->key==n)return temp;elsetemp=temp->left;}return NULL;}*/template<typename T>void rb_tree<T>::delen(T n){rbtree *rb_dele_node=findn(n);//rb_dele_node=rb_dele_node->p;//找前继rbtree *temp=rb_dele_node;rbtree *ad;//调整int rb_color=rb_dele_node->color;if(rb_dele_node->left==NULL)//左空{ad=rb_dele_node->right;rb_de_node(&rb_dele_node,&rb_dele_node->right);}else if(rb_dele_node->right==NULL)//{ad=rb_dele_node->left;rb_de_node(&rb_dele_node,&rb_dele_node->left);}else{temp=rb_dele_node->right;treemin(&temp);//找右最小值或左最大值rb_color=temp->color;rb_dele_node->key=temp->key;ad=temp->right;rb_de_node(&temp,&temp->right);//if(rb_dele_node==temp->p)}if(rb_color==black)rb_deletefixup(ad);} //---------------------删除结点性质修复-----------------------------------              //所有的工作,都在下述23行伪代码中:              /*             RB-DELETE-FIXUP(T, x)             1 while x ≠ root[T] and color[x] = BLACK             2     do if x = left[p[x]]             3           then w ← right[p[x]]             4                if color[w] = RED             5                   then color[w] ← BLACK                        ?  Case 1             6                        color[p[x]] ← RED                       ?  Case 1             7                        LEFT-ROTATE(T, p[x])                    ?  Case 1             8                        w ← right[p[x]]                         ?  Case 1             9                if color[left[w]] = BLACK and color[right[w]] = BLACK             10                   then color[w] ← RED                          ?  Case 2             11                        x p[x]                                  ?  Case 2             12                   else if color[right[w]] = BLACK             13                           then color[left[w]] ← BLACK          ?  Case 3             14                                color[w] ← RED                  ?  Case 3             15                                RIGHT-ROTATE(T, w)              ?  Case 3             16                                w ← right[p[x]]                 ?  Case 3             17                         color[w] ← color[p[x]]                 ?  Case 4             18                         color[p[x]] ← BLACK                    ?  Case 4             19                         color[right[w]] ← BLACK                ?  Case 4             20                         LEFT-ROTATE(T, p[x])                   ?  Case 4             21                         x ← root[T]                            ?  Case 4             22        else (same as then clause with "right" and "left" exchanged)             23 color[x] ← BLACK              */  template<typename T>void rb_tree<T>::rb_deletefixup(rbtree *ptr){while(ptr!=NULL&&ptr->color==black){if(ptr==ptr->left){rbtree *temp=ptr->p->right;//temp 兄弟节点if(temp->color==red)//ptr 兄弟节点红色{temp->color=black;ptr->p->color=red;left_rotate(ptr->p);temp=ptr->p->right;//新节点}if(temp->left->color==black&&temp->right->color==black)//ptr 兄弟节点w黑色,且w两个子节点黑色{temp->color=red;ptr=ptr->p;}else if(temp->right->color==black){temp->left->color=black;temp->color=red;right_rotate(temp);temp=ptr->p->right;//三种情况temp->color=ptr->p->color;ptr->p->color=black;temp->right->color=black;left_rotate(ptr->p);}}else{rbtree *temp=ptr->p->left;if(temp->color==red)//ptr 兄弟节点红色{temp->color=black;ptr->p->color=red;right_rotate(ptr->p);temp=ptr->p->left;//新节点}if(temp->right->color==black&&temp->left->color==black)//ptr 兄弟节点w黑色,且w两个子节点黑色{temp->color=red;ptr=ptr->p;}else if(temp->left->color==black){temp->right->color=black;temp->color=red;left_rotate(temp);temp=ptr->p->left;//三种情况temp->color=ptr->p->color;ptr->p->color=black;temp->left->color=black;right_rotate(ptr->p);}}}}template<typename T>void rb_tree<T>::treemin(rbtree **ptr){while((*ptr)->left!=NULL){*ptr=(*ptr)->left;}}template<typename T>void rb_tree<T>::rb_de_node(rbtree **ptr,rbtree **rb){rbtree *temp=*ptr;if(temp->p==NULL)root=*rb;else if(temp==temp->p->left)(*ptr)->p->left=*rb;else(*ptr)->p->right=*rb;if((*rb)!=NULL)(*rb)->p=temp->p;delete temp;}template<typename T>void rb_tree<T>::dleftrotate(rbtree *ptr){left_rotate(ptr);right_rotate(ptr->p->p);}template<typename T>void rb_tree<T>::drightrotate(rbtree *ptr){right_rotate(ptr);left_rotate(ptr->p->p);}int main(){  rb_tree<int> tree;  vector<int> v;  for(int i=0;i<20;i++)  v.push_back(i);  random_shuffle(v.begin(),v.end());  copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));  cout<<"\n";  for(int i=0;i<v.size();i++)  {  tree.insert(v[i]);  cout<<"insert"<<v[i]<<"\n";  }  tree.porder();  cout<<"\n";  for(int i=0;i<v.size();i++)  {  tree.delen(v[i]);  cout<<"d"<<v[i]<<"\n";  tree.porder();  cout<<"\n";  }}

原创粉丝点击