红黑树删除操作

红黑树删除操作:

红黑树要删除某个key值时,首先还是要查找该key值在树中的位置,查找方法和搜索二叉树方法相同.

要删除的结点分为两种情况:

1.有左右两个孩子都存在.两个孩子都存在时,在该节点的右子树中寻找其直接后继,找到后用其值替换要删除节点的值,然后问题转化为删除该节点的直接后继,直接后继是有一个右孩子或者没有孩子节点.

2.只有一个孩子或者没有子孩子.

以上两种均归纳为最多只有一个孩子节点的节点,只要将其仅有的一个孩子节点及其子树或者NULL直接提上来就行,删除的节点如果是红色则不会影响树的黑高,如果是黑色节点,则会影响树的黑高,树的平衡必然被打破,所以要进行调整.

现在将前面所说的提上来的节点(也就是删除节点的孩子节点,即删除了那个节点以后那个位置上的节点)以下称为x,  x 的兄弟节点记为w,如果x为红色节点则直接将红色节点更改为黑色,则又重新平衡,调整完成,如果x为黑色节点(即NULL)这种情况比较复杂 ,分为4种情况处理:

1.如果x的兄弟节点w是红色的,则x和w的父亲节点p一定是黑色的而且w的两个孩子也是黑色的(非null)则只要将p和w做一次左旋转并改变w的颜色为红色即平衡.



2.x的兄弟节点w是黑色(非NULL)且两个子节点是黑色(null),则将w变为红色,这样p节点的子树平衡.将x = x->parent,即上移,又回到了1.2.3.4的情况(以new 的x的子树还是少了一个黑色节点)同样的去检查,如果x为红色则将变为黑色调整完成,如果是黑色,则继续去检查x的new的兄弟节点是什么颜色.....


3.w的左孩子节点是红色,右节点是黑色(null),w和x的父亲节点p可红可黑,对w做一次左旋转,并调整颜色,则成为4的情况.



4.w的右孩子是红色,左边孩子是黑色(null).将x的父亲节点做一次左旋转,然后更改颜色,x的父亲p 为黑色,w为红色,则调整完成.


typedef int Type;
typedef enum{RED=0,  BLACK}COLOR;

typedef struct RBNode
{
	COLOR color;
	Type  data;
	RBNode *parent;
	RBNode *leftChild;
	RBNode *rightChild;
}RBNode;

typedef struct RBTree
{
	RBNode *root;
	RBNode *NIL;
}RBTree;

RBNode* _Buynode(Type v)
{
	RBNode *s = (RBNode*)malloc(sizeof(RBNode));
	assert(s != NULL);
	memset(s, 0, sizeof(RBNode));
	s->data = v;
	s->color = RED;
	return s;
}

void InitRBTree(RBTree &t)
{
	t.NIL = _Buynode(0);
	t.root = t.NIL;
	t.NIL->color = BLACK;
}

void LeftRotate(RBTree &t, RBNode *p)
{
	RBNode *s = p->rightChild;
	p->rightChild = s->leftChild;
	if(s->leftChild != t.NIL)
		s->leftChild->parent = p;
	s->parent = p->parent;
	if(p->parent == t.NIL)
		t.root = s;
	else if(p == p->parent->leftChild)
		p->parent->leftChild = s;
	else
		p->parent->rightChild = s;
	s->leftChild = p;
	p->parent = s;
}
void RightRotate(RBTree &t, RBNode *p)
{
	RBNode *s = p->leftChild;
	p->leftChild = s->rightChild;
	if(s->rightChild != t.NIL)
		s->rightChild->parent = p;
	s->parent = p->parent;

	if(p->parent == t.NIL)
		t.root = s;
	else if(p == p->parent->leftChild)
		p->parent->leftChild = s;
	else
		p->parent->rightChild = s;

	s->rightChild = p;
	p->parent = s;
}

void Insert_Fixup(RBTree &t, RBNode *z)
{
	RBNode *y;
	while(z->parent->color == RED)
	{
		if(z->parent == z->parent->parent->leftChild)
		{
			y = z->parent->parent->rightChild;
			if(y->color == RED)
			{
				z->parent->color = BLACK;
				y->color = BLACK;
				z->parent->parent->color = RED;
				z = z->parent->parent;
				continue;
			}
			else if(z == z->parent->rightChild)
			{
				z = z->parent;
				LeftRotate(t, z);
			}
			z->parent->color = BLACK;
			z->parent->parent->color = RED;
			RightRotate(t, z->parent->parent);
		}
		else
		{
			y = z->parent->parent->leftChild;
			if(y->color == RED)
			{
				z->parent->color = BLACK;
				y->color = BLACK;
				z->parent->parent->color = RED;
				z = z->parent->parent;
				continue;
			}
			else if(z == z->parent->leftChild)
			{
				z = z->parent;
				RightRotate(t, z);
			}
			z->parent->color = BLACK;
			z->parent->parent->color = RED;
			LeftRotate(t, z->parent->parent);
		}
	}
	t.root->color = BLACK;
}

bool Insert(RBTree &t, Type x)
{
	RBNode *pr = t.NIL;
	RBNode *s = t.root;
	while(s != t.NIL)
	{
		if(x == s->data)
			return false;
		pr = s;
		if(x < s->data)
			s = s->leftChild;
		else
			s = s->rightChild;
	}

	RBNode *q = _Buynode(x);
	q->parent = pr;
	q->leftChild = t.NIL;
	q->rightChild = t.NIL;
	q->color = RED;

	if(pr == t.NIL)
		t.root = q;
	else if(x < pr->data)
		pr->leftChild = q;
	else
		pr->rightChild = q;

	Insert_Fixup(t, q);
	return true;
}

RBNode* _Next(RBTree &t, RBNode *p)
{
	if(p!=t.NIL && p->rightChild!=t.NIL)
	{
		p = p->rightChild;
		while(p->leftChild != t.NIL)
			p = p->leftChild;
	}
	return p;
}

void Delete_Fixup(RBTree &t, RBNode *&x)
{
	RBNode *w;
	while(x!=t.root && x->color==BLACK)
	{
		if(x == x->parent->leftChild)
		{
			w = x->parent->rightChild;
			if(w->color == RED)
			{
				w->color = BLACK;
				x->parent->color = RED;
				LeftRotate(t, x->parent);
			}
			if(w->leftChild->color==BLACK && w->rightChild->color==BLACK)
			{
				w->color = RED;
				x = x->parent;
			}
			else if(w->rightChild->color == BLACK)
			{
				w->leftChild->color = BLACK;
				w->color = RED;
				RightRotate(t, w);
				w = x->parent->rightChild;
			}
			w->color = x->parent->color;
			x->parent->color = BLACK;
			w->rightChild->color = BLACK;
			LeftRotate(t, x->parent);
			x = t.root;
		}
		else
		{
			w = x->parent->leftChild;
			if(w->color == RED)
			{
				w->color = BLACK;
				x->parent->color = RED;
				RightRotate(t, x->parent);
			}
			if(w->leftChild->color==BLACK && w->rightChild->color==BLACK)
			{
				w->color = RED;
				x = x->parent;
			}
			else if(w->leftChild->color == BLACK)
			{
				w->rightChild->color = BLACK;
				w->color = RED;
				LeftRotate(t, w);
				w = x->parent->leftChild;
			}

			w->color = x->parent->color;
			x->parent->color = BLACK;
			w->leftChild->color = BLACK;
			RightRotate(t, x->parent);
			x = t.root;
		}
	}
	x->color = BLACK;
}

bool Remove(RBTree &t, Type key)
{
	RBNode *p = t.root;
	RBNode *y;
	RBNode *s;
	while(p!=t.NIL && p->data!=key)
	{
		if(key < p->data)
			p = p->leftChild;
		else
			p = p->rightChild;
	}
	//if(p->leftChild!=t.NIL || p->rightChild!=t.NIL)
	//	y = p;
	//else
	//	y = _Next(t, p);
	if(p->leftChild!=t.NIL && p->rightChild!=t.NIL)
		y = _Next(t, p);
	else
		y = p;

	if(y->leftChild != t.NIL)
		s = y->leftChild;
	else
		s = y->rightChild;


	s->parent = y->parent;
	if(y->parent == t.NIL)
		t.root = s;
	else if(y == y->parent->leftChild)
		y->parent->leftChild = s;
	else
		y->parent->rightChild = s;

	if(y != p)
		p->data = y->data;

	if(y->color == BLACK)
		Delete_Fixup(t, s);

	delete y;
	return true;

}
tianxintong@txt:~/git/shujia/Code@Bao/Test7_13_RBTree_C$ 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值