算法导论复习十四章

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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值