红黑树



一棵二叉查找树如果满足下面的红黑性质,则为一棵红黑树:

1)每个结点或是红的,或是黑的。

2)根结点是黑的。

3)每个叶子结点(nil)是黑的。

4)如果一个结点是红的,则他的两个儿子都是黑的。

5)对于每个结点,从该结点到其子孙结点(叶子结点)的所有路径包含的相同数目的黑结点。

 由于所有的叶子结点都是黑色,所以我们可以用一个结点nil来统一代表所有的叶子结点。


先定义2个结构体。

struct Node
{
	Node *left,*right,*p;//左儿子 右儿子 父亲 
	int key;
	int color;//0 red 1 black (2 NIL)
	Node()
	{
		key=color=-1;
		left=right=p=NULL;
	}
	Node(int k)
	{
		key=k;
		color=0;
		left=right=p=NULL;
	}
};
struct Tree
{
	Node *root,*nil;
	Tree()
	{
		nil=new Node();
		nil->color=1;
		nil->p=nil;
		root=nil;
		root->p=root;
	}
	
};
插入:

 插入结点z,并且把结点z着为红色。

void Insert(Tree *T,Node *z)
{
	Node *y=T->nil;
	Node *x=T->root;
	while(x!=T->nil)
	{
		y=x;
		if((z->key)<(x->key))	
			x=x->left;
		else
			x=x->right;	
	}
	z->p=y;
	if(y==T->nil)
		T->root=z;
	else 
		if((z->key)<(y->key))
			y->left=z;
		else
			y->right=z;
	z->left=T->nil;
	z->right=T->nil;
	z->color=0;//red
	Insert_Fixup(T,z);
}
插入过程中可能会破坏红黑树的某些性质。

由于插入的节点颜色是红色,所以破坏的性质要么是性质2,要么是性质4。 

a)结点z是红色,且z是根结点。 直接把z的颜色改为黑色。

 b)如果p【z】是黑色。 不做变化。 

c)如果p【z】是红色。

 case1:z的叔叔是红色。 把z的叔叔和z的父亲变为黑色(维持4属性),z的爷爷变为红色(维持5属性)。

 case2:z的叔叔是黑色,z是右孩子。

 case3:z的叔叔是黑色,z是左孩子。(case2 和 case 3相近)

给出前后变化:


变化后:


这段画画图看看代码就好理解

void Insert_Fixup(Tree *T,Node *z)
{
	while(z->p->color==0)//仅仅当case 1的时候while可执行多次 
	{
		if(z->p==z->p->p->left)
		{
			Node *y=z->p->p->right;
			if(y->color==0)//case 1 
			{
				z->p->color=1;
				y->color=1;
				z->p->p->color=0;
				z=z->p->p;
			}
			else
			{
				if(z==z->p->right)
				{
					z=z->p;
					Left_Rotate(T,z);
				}
				z->p->color=1;
				z->p->p->color=0; 
				Right_Rotate(T,z->p->p);
			}				
		}
		else//下面么这段代码是跟上面的那段代码left和right交换得到的 
		{
			Node *y=z->p->p->left;
			if(y->color==0)
			{
				z->p->color=1;
				y->color=1;
				z->p->p->color=0;
				z=z->p->p;
			}
			else
			{
				if(z==z->p->left)
				{
					z=z->p;
					Right_Rotate(T,z);
				}
				z->p->color=1;
				z->p->p->color=0;
				Left_Rotate(T,z->p->p);
			}				
		}
	}
	T->root->color=1;
}

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
struct Node
{
	Node *left,*right,*p;//左儿子 右儿子 父亲 
	int key;
	int color;//0 red 1 black (2 NIL)
	Node()
	{
		key=color=-1;
		left=right=p=NULL;
	}
	Node(int k)
	{
		key=k;
		color=0;
		left=right=p=NULL;
	}
};
struct Tree
{
	Node *root,*nil;
	Tree()
	{
		nil=new Node();
		nil->color=1;
		nil->p=nil;
		root=nil;
		root->p=root;
	}	
};
void Left_Rotate(Tree *T,Node* x)
{
	Node *y=x->right;
	x->right=y->left;
	if(y->left!=T->nil)
		y->left->p=x;
	y->p=x->p;
	if(x->p==T->nil)
		T->root=y;
	else
		if(x==x->p->left)
			x->p->left=y;
		else
			x->p->right=y;
	y->left=x;
	x->p=y;
}
void Right_Rotate(Tree *T,Node *x)
{
	Node *y=x->left;
	x->left=y->right;
	if(y->right!=T->nil)
		y->right->p=x;
	y->p=x->p;
	if(x->p==T->nil)
		T->root=y;
	else
		if(x==x->p->right)
			x->p->right=y;
		else
			x->p->left=y;
	y->right=x;
	x->p=y;
}
void Insert_Fixup(Tree *T,Node *z)
{
	while(z->p->color==0)//仅仅当case 1的时候while可执行多次 
	{
		if(z->p==z->p->p->left)
		{
			Node *y=z->p->p->right;
			if(y->color==0)//case 1 
			{
				z->p->color=1;
				y->color=1;
				z->p->p->color=0;
				z=z->p->p;
			}
			else
			{
				if(z==z->p->right)
				{
					z=z->p;
					Left_Rotate(T,z);
				}
				z->p->color=1;
				z->p->p->color=0; 
				Right_Rotate(T,z->p->p);
			}				
		}
		else//下面么这段代码是跟上面的那段代码left和right交换得到的 
		{
			Node *y=z->p->p->left;
			if(y->color==0)
			{
				z->p->color=1;
				y->color=1;
				z->p->p->color=0;
				z=z->p->p;
			}
			else
			{
				if(z==z->p->left)
				{
					z=z->p;
					Right_Rotate(T,z);
				}
				z->p->color=1;
				z->p->p->color=0;
				Left_Rotate(T,z->p->p);
			}				
		}
	}
	T->root->color=1;
}
void Insert(Tree *T,Node *z)
{
	Node *y=T->nil;
	Node *x=T->root;
	while(x!=T->nil)
	{
		y=x;
		if((z->key)<(x->key))	
			x=x->left;
		else
			x=x->right;	
	}
	z->p=y;
	if(y==T->nil)
		T->root=z;
	else 
		if((z->key)<(y->key))
			y->left=z;
		else
			y->right=z;
	z->left=T->nil;
	z->right=T->nil;
	z->color=0;//red
	Insert_Fixup(T,z);
}
void Delete_Fixup(Tree *T,Node *x) 
{
	Node *w;
	while(x!=T->root&&x->color==1)
	{
		if(x==x->p->left)
		{
			w=x->p->right;
			if(w->color==0)	
			{
				w->color=1;
				x->p->color=0;
				Left_Rotate(T,x->p);
				w=x->p->right;
			}
			if(w->left->color==1&&w->right->color==1)
			{
				w->color=0;
				x=x->p;
			}
			else
				if(w->right->color==1)
				{
					w->left->color=1;
					w->color=0;
					Right_Rotate(T,w);
					w=x->p->right;
				}
				w->color=x->p->color;
				x->p->color=1;
				w->right->color=1;
				Left_Rotate(T,x->p);
				x=T->root;	
		}
		else
		{
			w=x->p->left;
			if(w->color==0)	
			{
				w->color=1;
				x->p->color=0;
				Right_Rotate(T,x->p);
				w=x->p->left;
			}
			if(w->right->color==1&&w->left->color==1)
			{
				w->color=0;
				x=x->p;
			}
			else
				if(w->left->color==1)
				{
					w->right->color=1;
					w->color=0;
					Left_Rotate(T,w);
					w=x->p->left;
				}
				w->color=x->p->color;
				x->p->color=1;
				w->left->color=1;
				Right_Rotate(T,x->p);
				x=T->root;
		}
	}
}
Node *Tree_Min(Tree *T,Node* x)
{
	while(x->left!=T->nil)
		x=x->left;
	return x;
}
Node *Tree_Successor(Tree *T,Node* x)//后继 
{
	Node *y;
	if(x->right!=T->nil)
		return Tree_Min(T,x->right);
	y=x->p;
	while(y!=T->nil&&x==y->right)
	{
		x=y;
		y=y->p;
	}
	return y;	
}
void Delete(Tree *T,Node *z) 
{
	Node *y,*x;
	if(z->left==T->nil||z->right==T->nil)
		y=z;
	else
		y=Tree_Successor(T,z);//z后继 
	if(y->left!=T->nil)
		x=y->left;
	else
		x=y->right;
	x->p=y->p;
	if(y->p==T->nil)
		T->root=x;
	else
		if(y==y->p->left)
			y->p->left=x;
		else
			y->p->right=x;
	if(y!=z)
	{
		z->key=y->key;//把y中的内容复制到z中 
	}
	if(y->color==1)
		Delete_Fixup(T,x);
	free(y);
}
void dfs(Tree *T,Node *x,int k)
{
	if(k>=5)
		return;
	if(x==T->nil)
		return;
	cout<<"-------"<<endl;
	cout<<x->key<<endl;
	cout<<x->left->key<<endl;
	cout<<x->right->key<<endl;
	dfs(T,x->left,k+1);
	dfs(T,x->right,k+1);
}	
void show(Tree *T)
{
	dfs(T,T->root,0);
}
Node *Search(Tree *T,Node *x,int key)
{
	if(x==T->nil)
		return T->nil;
	if(x->key==key)
		return x;
	if(x->key>key)
		return Search(T,x->left,key);
	else
		return Search(T,x->right,key);
}
int main()
{
	Tree T;
	Insert(&T,new Node(1));
	Insert(&T,new Node(2));
	Insert(&T,new Node(3));
	show(&T);
	Node *p=Search(&T,T.root,2);
	if(p!=T.nil)
		Delete(&T,p);

	show(&T);
	return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值