<RBT> 红黑树

红黑树: 一个平衡的二叉树,但不是一个完美的平衡二叉树。 查找在~lgN次比较内结束,但是这样在动态插入中保持树的完美平衡代价太高,所以,我们稍微放松逛一下限制,希望找到一个能在对数时间内完成查找的数据结构。
五条性质:
性质一:节点是红色或者是黑色;
在树里面的节点不是红色的就是黑色的,没有其他颜色,要不怎么叫红黑树呢,是吧。
性质二:根节点是黑色;
根节点总是黑色的。它不能为红。
性质三:每个叶节点(NIL或空节点)是黑色;
性质四:每个红色节点的两个子节点都是黑色的(也就是说不存在两个连续的红色节点);
就是连续的两个节点不能是连续的红色,连续的两个节点的意思就是父节点与子节点不能是连续的红色。
性质五:从任一节点到其没个叶节点的所有路径都包含相同数目的黑色节点;

插入分类:

    1.根

    2.黑色下面

    3红色下面

        父红 叔黑================父红叔红

        父黑祖父红  Turn                              父黑叔黑祖父红(con)

删除操作: (找真正删除节点)

    1.两个孩子

    2.根    一个/零个孩子

    3没有孩子

================================>

     1.红色节点

     2.黑色一个红孩    

    3.黑色没有孩子 看兄弟

        兄弟红色  染黑旋转

        兄弟黑色      

        1)左右双黑      2)左红右黑                                                      3)右红

            兄红{父红染黑        右侧 兄红左黑右旋pb(con)                                    右侧 兄呈父色   右黑父黑左旋pf

                    父黑 上调}               兄呈父色 左黑父黑右旋pf                        兄红右黑左旋pb  (con)

            







#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define f(i,l,r) for(int i=l;i<=r;++i)
#define g(i,l,r) for(int i=l;i>=r;--i)

enum Color{black,red};
typedef struct _RBTNode {
	int val;
	int color;
	struct _RBTNode * f,*l,*r;
}rbt;
rbt *pRbt = NULL;
rbt * createNode(int val){
	rbt *p =(rbt *)malloc(sizeof(rbt));
	p->val = val;
	p->f = NULL;
	p->l = NULL;
	p->r = NULL;
	p->color =red;

	return p;
}
void leftTurn(rbt ** pRoot){
	if(pRoot ==NULL) return ;

	rbt * t = *pRoot;
	rbt * pf = t->f;
	rbt * pl = t->l;
	rbt * pr = t->r;
	rbt * prl;
	if(pr)
		prl = t->r->l;
	if(prl)
		prl->f=t;
	t->r=prl;
	pr->l =NULL;
	if(pf==NULL) pRbt =pr;
	else 
	{
		if(pf->l==t)pf->l=pr;
		else
			pf->r=pr;
	}
	pr->f=pf;
	pr->l=t;
	t->f=pr; 
}
void rightTurn(rbt ** pRoot ){
	if(pRoot ==NULL) return ;

	rbt * t = *pRoot;
	rbt * pf = t->f;
	rbt * pl = t->l;
	rbt * pr = t->r;
	rbt * plr;
	if(pl)
		plr = t->l->r;
	if(plr)
		plr->f=t;
	t->l =plr;
	pl->r=NULL;
	if(pf==NULL)
	{
		pRbt=pl;
	}
	else 
	{
		if(pf->l==t)pf->l=pl;
		else
			pf->r=pl;
	}
	pl->f=pf;
	pl->r=t;
	t->f=pl; 
}
rbt * findfnode(int val){
	if(pRbt ==NULL) return NULL;
	rbt * t =pRbt;
	while(1)
	{
		if(t->l && t->val >val)
			 t=t->l;
		if(t->r&& t->val <val)
			 t=t->r;
		if((t->l==NULL && t->val >val)||(t->r==NULL && t->val <val))
			  break;
	}
	return t; 
}
rbt * GetUncle(rbt *  p ){
	rbt* gf = p->f->f;
	rbt* uncle;
	if(gf->l == p->f) uncle = gf->r;
	else uncle = gf->l;
	return uncle;
}
void insert(int val){
	if(pRbt == NULL) {
		pRbt =createNode(val);
		pRbt->color =black ;
		return ;
	}
	rbt * t = createNode(val);
	rbt * f = findfnode(val);
	rbt * gf, *uncle ;
	if(f->val >t->val)
	{
		t->f=f;
		f->l= t;
	}
	else
	{
		t->f=f;
		f->r=t;
	}
	//连接上以后判断情况 
	if(f->color == black)
		return;
	//父节点为红色 看叔叔节点
	while(f->color ==red)
	{
		gf =f->f;
		if(gf==NULL) return;
		uncle = GetUncle(t) ;

		//如果叔叔是红色
		if(uncle && uncle->color==red)
		{
			f->color =black;
			uncle->color =black;
			gf->color=red;
			if(gf==pRbt)
			{
				gf->color=black;
				return ;
			}
			t=f;
			f=gf;
			continue;
		}
		//叔叔是黑色 
		if(uncle==NULL || uncle->color ==black)
		{
			gf = f->f;
			if(gf->l==f)
			{ 
				if(t=f->l)
				{
					//父黑祖父红
					f->color=black;
					gf->color =red;
					 rightTurn(&f);
					return ; 
				}
				else
				{
					 t=f; 
					 leftTurn(&f);
					 f=t->f;
					continue; 
				} 
			}
			else
			{
				gf = f->f;
				if(t=f->l)
				{
					t=f;
					 rightTurn(&t);
					f=t->f;
					return ;
				}
				else
				{
					f->color=black;
					gf->color =red;
					 leftTurn(&gf);
					return;
				}
			}
		} 
	}
}
void print(rbt * pRbt)
{
	if(pRbt ==NULL) return ;
	printf("%d ===  %d  \n",pRbt->val ,pRbt->color);
	print(pRbt->l);
	print(pRbt->r);
}
void build (int * a,int n){
	if(a==NULL||n<=0)return ;
	f(i,0,n-1)
	{
		insert(a[i]);
	//	print(pRbt);
	}
}
rbt * select_node(int val){
	if(pRbt ==NULL) return NULL;
	rbt * t =pRbt;
	while(1)
	{
		if(t->l && t->val >val)
			 t=t->l;
		if(t->r&& t->val <val)
			 t=t->r;
		if(t->val ==val )return t;
	}
	return NULL; 
}

 rbt *GetBrother(rbt * t)
 {
	 if(t==NULL)return NULL;
	 if(t->f->l ==t)return t->f->r;
	 else return t->f->l;
 }
void delnode(int val){
	rbt * t = select_node(val);
	if(t==NULL) return ;
	
	rbt *pMark =NULL; 
	rbt *pf ;
	//有两个孩子 
	if(t->l && t->r)
	{
		rbt * d = t->l;
		while(d->r)d=d->r;
		d->f->r=NULL;
		t->val = d->val;
		pMark =d; 
	}
	//1.根没有孩子 或者 2 根有一个孩子
	if(t==pRbt &&(t->l==NULL&&t->r==NULL)||(t->l&&t->r==NULL)||(t->r&&t->l==NULL))
	{
		pRbt = t->l?t->l:t->r;
		pMark = t;
	}
	//红色节点
	if(t->color ==red)
	{
		pf=t->f;
		if(pf->l==t)
			pf->l =NULL;
		else
			pf->r=NULL;
		return ;
	}
	// 黑色 有一个红孩子
	if(t->color==black && (t->l&&t->r==NULL) ||(t->r&&t->l==NULL))
	{
		if(t->l) 
		{
			t->val=t->l->val;
			pMark =t->l;
			t->l=NULL;
		}
		else
		{
			t->val=t->r->val;
			pMark =t->r;
			t->r=NULL;
		}
	}


	//黑色没有孩子 看兄弟
	pf=t->f;
	rbt * pb =GetBrother(t);
	pMark =t;
	if(pf->l==t)
		pf->l=NULL;
	else pf->r=NULL;

	while(1)
	{
		//兄弟是红的 染黑旋转
		if(pb && pb->color==red)
		{
			pb->color=black;
			pf->color=red;
			if(pb=pf->l){
				pb=pb->r;
				rightTurn(&pf);
				continue;
			}
			else 
			{
				pb=pb->r;
				leftTurn(&pf);
				continue;
			}
		}
		//兄弟是黑的
		if(pb && pb->color==black)
		{
			//两个侄子都是黑的
			if(pb->l&&pb->r || (pb->l&&pb->r==NULL) || (pb->r&&pb->l==NULL)	)
			{
				pb->color = red;
				if(pf->color==red)
				{
					pf->color=black;
					break;
				}
				else
				{
					t=pf;
					pf=t->f;
					if(pf==NULL) break;
					pb=GetBrother(t);
					continue;
				}
			}
			//佐侄子 红 右黑 
			if(pb ->l && pb->l->color==red && pb->r==NULL|| pb->r->color==black)
			{
				if(pb=pf->r)
				{
					pb->color=red;
					pb->l->color=black;
					rightTurn(&pb);
					pb=GetBrother(t);
					continue;
				}
				else
				{
					pb->color=pf->color;
					pb->l->color=black;
					pf->color=black;

					rightTurn(&pf);
					break;
				}
			}
			//右侄子是红色
			if(pb->r &&pb->r->color==red)
			{
				if(pb==pf->r)
				{
					pb->color=pf->color;
					pf->color=black;
					pb->r->color=black;
					leftTurn(&pf);
					break;
				}
				else
				{
					pb->r->color=black;
					pb->color=red;
					leftTurn(&pb);
					pb=pb->f;;
					continue;
				}
			} 
		}
	}
	 

	free(pMark);
	pMark=NULL;



}

int main(){
	int a[]={2,4,9,45,61,3,1 };
	int n = sizeof(a)/sizeof(a[0]);
	build(a,n);
	 
	print(pRbt);

	return 0;

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值