//持续更新
#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;
}