//持续更新
#include <iostream>//动态顺序统计,要分析好对于新添加的信息size在插入,删除以及旋转的时候的变换,直接从这种变化出发进行解决是最好的,也可以采用一种修正后的调整就是插入之后再进行调整之类 #define RED 1 #define BLACK 0 using namespace std; struct node { int key; node* p; node* left; node* right; bool color; int size; node(){ key=0; p=NULL; left=NULL; right=NULL; color=RED; size=1; } node(int k):key(k){ p=NULL; left=NULL; right=NULL; color=RED; size=1; } node(int k ,int s):key(k),size(s){ p=NULL; left=NULL; right=NULL; color=RED;//这个是nil使用的 } node& operator=(node& other) { if(this!=&other) { this->key=other.key; this->p=other.p; this->color=other.color; this->left=other.left; this->right=other.right; } return *this; } void init() { size=left->size+right->size+1; } }; struct rbtree { node* root;//根 node* nil;//哨兵 rbtree() { int k; cin>>k; root=new node(k); root->color=BLACK; nil=new node(100000,0);//size为0 nil->color=BLACK; root->p=nil;//一开始根节点就指向该值 root->left=nil;//最初的时候如此的进行设计。 root->right=nil; } void letf_rotate(node*);//o(1) void right_rotate(node*);//o(1) void rb_insert_fixup(node*); void rb_insert(node*);//o(lgn) void rb_delete_fixup(node*); node* rb_delete(node*);//o(lgn) node* rb_successor(node*);//辅助 node* rb_min(node*);//辅助 node* os_select(node*,int); int os_rank(node*); }; node* rbtree::os_select(node* x,int i) { int r=x->left->size+1; if(r==i) return x; else if(r<i) return os_select(x->left,i); else return os_select(x->right,r-1); } int rbtree::os_rank(node *x) { int r=x->left->size+1; node* y=x; while(y!=root) { if(y=y->p->right) { r=r+y->p->left->size+1; y=y->p; } } return r; } void rbtree::letf_rotate(node* px) { node* py=px->right; if(py!=nil) { px->right=py->left; if(py->left!=nil) py->left->p=px; py->p=px->p; if(px==nil) root=py; if(px==px->p->left) px->p->left=py; else px->p->right=py; py->left=px; px->p=py; } else { cerr<<"left of px is null "<<endl; return ;//一般情况下函数返回值为void 可以如此; } py->size=px->size; px->size=px->left->size+px->right->size+1; cout<<"finished! "<<endl; } void rbtree::right_rotate(node* px)//13.2-1 { node* py=px->left; if(py!=nil) { px->left=py->right; if(py->right!=nil) py->right->p=px; py->p=px->p; if(px->p==nil) root=py; if(px==px->p->left) px->p->left=py; else px->p->right=py; py->right=px; px->p=py; }else { cerr<<"right of px is nil "<<endl; return ; } py->size=px->size; px->size=px->left->size+px->right->size+1; cout<<"finishede!"<<endl; } /************rbtree_insert()************************/ void rbtree::rb_insert_fixup(node* pz) { node* py=new node(); while(pz->p->color==RED)//对于红黑树,插入一个点为红,只要保证最后的树是满足红黑树的五个性质即可,插入的是红点,黑高度不影响,那么插入 {//红点,会造成的影响是:如果插入的点成为根节点的话;以及插入节点的父节点为红。这里以插入节点的父节点为红做判断。 if(pz->p==pz->p->p->left) { py=pz->p->p->right;//py为pz的叔叔 if(py->color==RED)//情况1:叔叔为红的时候 { pz->p->color=BLACK; py->color=BLACK; pz->p->p->color=RED;//修改颜色使父辈变黑,爷爷变红,这样节点黑高度不受影响,原因是pz为红,pz父辈为红,那么对应必定有祖父辈,插入前的rbtree为 //正常的,父辈不会为根,那么存在祖父辈,如果祖父辈为红,父辈怎么会为红呢?祖父辈必定为黑以保证插入前的rbtree是正常。 pz=pz->p->p; }else { if(pz==pz->p->right)//情况2:叔叔为黑,且pz是右孩子 { pz=pz->p; letf_rotate(pz); } pz->p->color=BLACK;//情况3:叔叔为黑,pz是左孩子 pz->p->p->color=RED; right_rotate(pz->p->p); } }else if(pz->p==pz->p->p->right) { py=pz->p->p->left;//叔叔 if(py->color==RED) { pz->p->color=BLACK; py->color=BLACK; pz->p->p->color=RED; pz=pz->p->p; }else { if(pz==pz->p->left) { pz=pz->p; right_rotate(pz); } pz->p->color=BLACK; pz->p->p->color=RED; letf_rotate(pz->p->p); } } } root->color=BLACK;//这里的做法,可以避免插入的节点成为根节点,黑高度还是不受影响,只是大了一个 // delete py; } void rbtree::rb_insert(node* pz)//红黑树是二叉查找树,插入节点先图红,可以保证节点黑高度,插入的是类似二叉查找树的插入 { node* py=nil; node* px=root; while(px!=nil) { px->size++; py=px; if(pz->key>px->key) px=px->right; else px=px->left; } pz->p=py; if(py==nil) root=pz; else if(pz->key<py->key) py->left=pz; else py->right=pz; pz->left=nil; pz->right=nil; pz->color=RED; rb_insert_fixup(pz); // delete py; // delete px; } int main() { rbtree* rb=new rbtree(); node* p1=new node(1); node* p2=new node(2); node* p3=new node(3); // rb->letf_rotate(p1);//一开始运行此处的时候会报错,原因很简单,在上面的py->left等都是空的。所以赋值的时候会出错的。勿怪了 // rb->right_rotate(p2); rb->rb_insert(p1); rb->rb_insert(p2); rb->rb_insert(p3); return 0; }
/* 区间树:同样是基于红黑树的结构进行添加的区间特性,和14.1节的特性(添加了size特性)都是一个道理; 区间概念:即[t1,t2](t1<=t2),把区间当做是一个对象i,相应的可以知道的就是区间存在的有的域 low[i]=t1,high[i]=t2; 区间存在着对应的关系:1,重叠;2,区间1,在区间2左边即high[i1]<low[i2];3,区间1在区间2右边,即high[i2]<low[i1] 区间树的操作:1,插入:把包含区间域的元素插入到区间树中;2,删除:把包含区间域的某元素从树中删除;3,查找:即在区间树中 查找某一个区间域对象,如果没有就返回null 基础数据结构:基于红黑树,每一个节点x包含区间域int[x],节点x关键值为区间的低端点low[int[x]],还有声明的就是使用的是中序遍历 附加信息:每一个节点中还包含了一个值max[x],表示为以x为根的子树中所有区间的端点最大值; 信息的维护:对于附加信息就表示为:对于节点x,对应的最大值max[x]表示为max[x]=max(high[x],max[left[x]],max[right[x]]); */ #include <iostream> #include <algorithm> #define RED 1 #define BLACK 0 using namespace std; struct range { int start; int end; range() { cin>>start; cin>>end; } bool overlap(range rge) { if(this->start>rge.end||this->end<rge.start) return false; return true; } range& operator=(range& other) { if(this!=&other) { this->start=other.start; this->end=other.end; } return *this; } }; struct node { int key; node* p; node* left; node* right; bool color; range rge; int Max; node(){ key=0; p=NULL; left=NULL; right=NULL; color=RED; rge.start=0; rge.end=0; Max=rge.end; } node(int k):key(k){ p=NULL; left=NULL; right=NULL; color=RED; rge.start=0; rge.end=0; Max=rge.end; } node(int k,int s,int e):key(k){ rge.start=s; rge.end=e; p=NULL; left=NULL; right=NULL; color=RED; Max=rge.end; } node& operator=(node& other) { if(this!=&other) { this->key=other.key; this->p=other.p; this->color=other.color; this->left=other.left; this->right=other.right; this->Max=other.Max; this->rge=other.rge; } return *this; } }; struct rbtree { node* root;//根 node* nil;//哨兵 rbtree() { int k; cin>>k; root=new node(k); root->color=BLACK; nil=new node(100000); nil->color=BLACK; root->p=nil; root->left=nil; root->right=nil; } void letf_rotate(node*); void right_rotate(node*); void rb_insert_fixup(node*);//这里需要的是插入区间,我们使用节点代替。 void rb_insert(node*); void rb_delete_fixup(node*); node* rb_delete(node*); node* rb_successor(node*); node* rb_min(node*); node* rb_search(node*); int max(int ,int); }; /* 对于插入的是某一个节点,相应的在插入的时候需要调整的是维护的最大值。 */ int rbtree::max(int a,int b) { return a>b?a:b; } node* rbtree::rb_search(node* pz) { node* px=root; while(px!=nil&&!(pz->rge.overlap(px->rge))) { if(px->left!=nil&&px->left->Max>=pz->rge.start) { px=px->left; }else px=px->right; } return px; } void rbtree::letf_rotate(node* px) { node* py=px->right; if(py!=nil) { px->right=py->left; if(py->left!=nil) py->left->p=px; py->p=px->p; if(px==nil) root=py; if(px==px->p->left) px->p->left=py; else px->p->right=py; py->left=px; px->p=py; } else { cerr<<"left of px is null "<<endl; return ; } py->Max=px->Max; int MAX=max(px->left->Max,px->right->right->Max); px->Max=max(px->rge.end,MAX); cout<<"finished! "<<endl; } void rbtree::right_rotate(node* px) { node* py=px->left; if(py!=nil) { px->left=py->right; if(py->right!=nil) py->right->p=px; py->p=px->p; if(px->p==nil) root=py; if(px==px->p->left) px->p->left=py; else px->p->right=py; py->right=px; px->p=py; }else { cerr<<"right of px is nil "<<endl; return ; } py->Max=px->Max; int MAX=max(px->left->Max,px->right->right->Max); px->Max=max(px->rge.end,MAX); cout<<"finishede!"<<endl; }//旋转的时候需要调整区间的值 void rbtree::rb_insert_fixup(node* pz) { node* py=new node(); while(pz->p->color==RED) { if(pz->p==pz->p->p->left) { py=pz->p->p->right; if(py->color==RED) { pz->p->color=BLACK; py->color=BLACK; pz->p->p->color=RED; pz=pz->p->p; }else { if(pz==pz->p->right) { pz=pz->p; letf_rotate(pz); } pz->p->color=BLACK; pz->p->p->color=RED; right_rotate(pz->p->p); } }else if(pz->p==pz->p->p->right) { py=pz->p->p->left; if(py->color==RED) { pz->p->color=BLACK; py->color=BLACK; pz->p->p->color=RED; pz=pz->p->p; }else { if(pz==pz->p->left) { pz=pz->p; right_rotate(pz); } pz->p->color=BLACK; pz->p->p->color=RED; letf_rotate(pz->p->p); } } } root->color=BLACK; } void rbtree::rb_insert(node* pz) {//插入以及删除的时候需要进行修改 node* py=nil; node* px=root; while(px!=nil) { px->Max=max(pz->Max,px->Max); py=px; if(pz->key>px->key) px=px->right; else px=px->left; } pz->p=py; if(py==nil) root=pz; else if(pz->key<py->key) py->left=pz; else py->right=pz; pz->left=nil; pz->right=nil; pz->color=RED; rb_insert_fixup(pz); } node* rbtree::rb_min(node* pz) { while (pz->left!=nil) { pz=pz->left; } return pz; } node* rbtree::rb_successor(node* pz)//中序遍历求后继 { node* py=new node(); if(pz->right!=nil) return rb_min(pz->right); py=pz->p; while (py!=nil&&pz==py->right) { pz=py; py=py->p; } return py; } void rbtree::rb_delete_fixup(node* pz) { node* pw=new node(); while(pz!=root&&pz->color==BLACK)//为根节点,整体黑高度不影响,为红,后面会涂黑。 { if(pz==pz->p->left) { pw=pz->p->right; if(pw->color==RED)//只有是父节点是黑色的情况pw才可能是红色。 { pz->p->color=RED; pw->color=BLACK; letf_rotate(pz->p); pw=pz->p->right; }//情况1 if (pw->left->color==BLACK&&pw->right->color==BLACK) { pw->color=RED;//只用堆pw修改,pz实际上是黑的,去掉一重还是黑,不要改,但是pw要; pz=pz->p;//此操作结束后,pz为红,结束并涂黑,如果pz为黑,还要pz加一重黑 } else { if(pw->right->color==BLACK)//情况3 { pw->left->color=BLACK; pw->color=RED; right_rotate(pw); pw=pz->p->right; }//情况4 pw->color=pz->p->color; pz->p->color=BLACK; pw->right->color=BLACK; letf_rotate(pz->p); pz=root; } } else if(pz==pz->p->right) { pw=pz->p->left;//叔叔 if(pw->color=RED) { pz->p->color=RED; pw->color=BLACK; right_rotate(pz->p); pw=pz->p->left; } if(pw->left->color==BLACK&&pw->right->color==BLACK) { pw->color=RED; pz=pz->p; } else { if(pw->right->color==BLACK) { pw->left->color=BLACK; pw->color=RED; letf_rotate(pw); pw=pz->p->left; } pw->color=pz->p->color; pz->p->color=BLACK; pw->right->color=BLACK; right_rotate(pz->p); pz=root; } } } pz->color=BLACK; } node* rbtree::rb_delete(node* pz) { node* py=new node(); node* px=new node(); node* p=new node(); if (pz->left==nil||pz->right==nil) { py=pz; p=py->p; p->Max=p->rge.end; while(p->Max==py->Max) { p->Max=max(p->Max,max(p->left->Max,p->right->Max)); p=p->p; } } else py=rb_successor(pz); p=py->p; p->Max=p->rge.end; while(p->Max==py->Max) { p->Max=max(p->Max,max(p->left->Max,p->right->Max)); p=p->p; } if(py->left!=nil) px=py->left; else px=py->right; px->p=py->p; if(py==nil) root=px; else if(py==py->p->left) py->p->left=px; else py->p->right=px; if(py!=pz) { pz->key=py->key; pz->rge=py->rge; pz->Max=py->Max; p=pz->p; while(p->Max<pz->Max) { p->Max=pz->Max; p=p->p; } } if (py->color==BLACK) { rb_delete_fixup(px); } return py; } /*********************main_function()************************************/ int main() { rbtree* rb=new rbtree(); node* p1=new node(1); node* p2=new node(2); node* p3=new node(3); rb->rb_insert(p1); rb->rb_insert(p2); rb->rb_insert(p3); rb->rb_delete(p2); delete p1; delete p2; delete p3; return 0; }
算法导论复习十四章
最新推荐文章于 2022-09-14 20:37:13 发布