红黑树删除——C语言

本文介绍了红黑树的删除操作,分为两步:先按二叉查找树删除节点,然后进行树的修正。对于删除的黑色节点,需要进行特定的修正操作,包括旋转和颜色调整。通过代码实现并运行,强调了理解和实践的重要性。
摘要由CSDN通过智能技术生成

 红黑树的删除——C语言

昨天理解了红黑树的定义、插入,旋转(左旋右旋)及相关代码实现,今天继续红黑树的删除。

可以先进行总结的是:红黑树的删除也是分两步走——第一步:像一个普通二叉查找树一样删除结点;第二步:对删除后的树进行修正。具体操作如下:


1、第一步:像一个普通二叉查找树一样删除结点并根据被删除结点的颜色决定下一步该怎么做。

                    //(二叉查找树删除①当待删除结点有两个孩子的时候,找到右孩子的左叶子或左孩子的右叶子,替换删除;②当待删除结点一个孩子的时候,把它的孩子接在待删除结点父结点上再删除;③叶子结点直接删除)

                    ·当被删除结点是红色时——不需要修正,删除操作结束;

                    ·当被删除结点是黑色时——需要进行修正(见第二步)。


2、第二步:对删除后的树进行修正。

                    //待修正结点为N

                    ·N兄弟为红,其它都为黑时——对N父亲左旋,父兄互换颜色;

                    ·N兄弟为黑,且N兄弟为右时——

                                                   ·若N兄弟左孩子为红,右孩子为黑——N兄弟右旋,N兄弟和N兄弟左孩子互换颜色;

                                                   ·若N兄弟右孩子为红,左孩子任意——N父亲左旋,N兄弟和N父亲互换颜色,兄弟右孩子涂黑;

                                                   ·若N兄弟左,右孩子都为黑——N的兄弟涂红,研究父节点。

                      ·最后待修正结点不管什么颜色都涂黑。

删除修正


删除结点代码实现: 

//删除 
void rbtree_delete(RBRoot *root,Node *node)
{
	Node *temp,*child,*parent;//替换结点 
	int color;
	//当node有俩孩子时
	if((node->lchild!=NULL)&&(node->rchild!=NULL))
	{ 	
		//找到待删除结点的后继结点,即右子树的最左边的叶子结点 
		temp=node->rchild;
		parent=node->parent;
		while(temp->lchild!=NULL)
		{
			temp=temp->lchild;
		}
		//判断待删除结点是否为根节点
		if(node->parent!=NULL) 
		{//不为根
			if(node==node->parent->lchild)
			{
				node->parent->lchild=temp;
			} 
			 else 
			{
			 	node->parent->rchild=temp;
			}
		}
		else
		{//为根 
			root->node=temp;
		}
		parent=temp->parent;//parent标记temp父结点 
		
		//child是temp的右孩子,temp必然没有左孩子,必然要对child进行调整; 
		child=temp->rchild;
		
		
		//判断temp是否为node的父节点
		if(parent==node)
		{//是,直接替代 
			parent=temp;	
		} 
		else
		{//不是,调整 
		 //child若存在,则设为parent的左孩子
		if(child!=NULL)
			{
		 		child->parent=parent;
			} 
		parent->lchild=child;
		temp->rchild=node->rchild;
		node->rchild->parent=temp;
		}
		temp->parent=node->parent;
		temp->color=node->color;
		temp->lchild=node->lchild;
		node->lchild->parent=temp;
	}
	else
	{//若只有1个孩子
		if(node->lchild!=NULL)
		{
			child=node->lchild;
		} 
		else
		{
			child=node->rchild;
		}
		parent=node->parent;
		color=node->color;
		
		if(child!=NULL)
		{
			child->parent=parent;
		}
		if(parent!=NULL)
		{//node不为根时 
			if(parent->lchild==node)
			{
				parent->lchild=child;	
			} 
			else
			{
				parent->rchild=child;
			}
		}
		else
		{//node为根 
			root->node=child;
		}
		
	}
	if(color==BLACK)
		{
			rbtree_delete_fixup(root, child, parent);
			free(node);
			return; 
		}	 
 } 

删除修正代码实现:

//删除修正
void rbtree_delete_fixup(RBRoot *root,Node *node,Node *parent)
{
	Node *bro;
	int color;
	while((node!=root->node)&&(node->color!=BLACK||node==NULL))//当待调结点是根结点并且是黑色的或者是空的,就跳出循环 
	{  
		if(parent->lchild==node)
		{//若待调结点是左孩子
			br
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值