红黑树代码
来源:互联网 发布:编程笔记本配置要求 编辑:程序博客网 时间: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"; }}