红黑树原理(增加节点、删除节点、修改节点、查询节点)

红黑树定义

 1. 节点颜色非红即黑
 2. 根节点颜色是黑色
 3. 叶子节点(空节点)颜色为黑色
 4. 红色节点的子节点(包括空节点)为黑色
 5. 某个节点下的所有路径,有相同的黑色节点(包括空节点(黑色))

在这里插入图片描述

红黑树增删改查演示地址https://www.cs.usfca.edu/~galles/visualization/RedBlack.html
示例数据:12,1,9,2,3,0,11,7,19,4,15,18,5,14,13,10,16,6,8,17

1. 红黑树增加节点过程

 增加一个节点,节点颜色默认为红色,对红黑树进行二分查找,对比,
 直至整个红黑树的叶子节点,确定当前节点插入红黑树的初始位置(插入节点
 初始位置为整个红黑树的叶子节点)

	1、判断插入节点是否为根节点,如果是根节点
		把当前节点置为根节点,并把颜色置为黑色
	2、判断父节点的颜色,如果父节点的颜色为黑色
		不用处理,不违反红黑树的性质
	3、父节点是红色,叔叔节点也是红色
		3.1、将父节点和叔叔节点设置为黑色,祖父节点设置为红色
		3.2、以祖父节点为插入节点,在进行判断
	4、父节点是红色,叔叔节点是黑色
		4.1、左左插入
			父节点变成黑色,祖父节点变成红色,祖父节点右旋
		4.2、左右插入
 	    	父节左旋,之后父节点就变成了子节点
	 	 	按照父节点为当前插入的红色节点,进行左左插入处理
		4.3、右右插入
			父节点变成黑色,祖父节点变成红色,祖父节点左旋
		4.4、右左插入
 	    	父节点右旋,之后父节点变成了子节点
 	    	按照父节点为当前插入的红色节点,进行右右插入处理

演示:
在这里插入图片描述
假如需要插入数字3,则查找节点,数字3的初始位置为 数字2 节点的右子树,如下图:
在这里插入图片描述
根据插入的判断条件,从第一条依次向下进行判断,符合4.3:父节点(数字2)是红色,叔叔节点(数字2 的左子节点空节点)为黑色(空节点)条件,右右的情况,父节点(数字2)变成黑色,祖父节点(数字1)变成红色,祖父节点(数字1)左旋,得到最终的结果,如下图:
在这里插入图片描述

2. 红黑树删除节点过程

总结:
	删除节点时,先看删除节点的颜色,再看兄弟节点的颜色,再看侄子节点的颜色(先看远侄子,再看近侄子)
最后看父节点的颜色
	当前节点->兄弟节点->远侄子节点->近侄子节点->父节点
	(补充)删除节点分两种情况,一种是叶子节点,一种不是叶子节点,如果不是叶子节点,进行和子节点值
的交换,直至节点没有叶子节点,变成删除叶子节点
	1、删除的是叶子节点,并且叶子节点为红色
		直接删除,不需要后续处理
	2、删除的是叶子节点,并且叶子节点为黑色
		需要处理
	3、删除节点下有一个子节点
		将当前删除的节点和子节点的值进行交换,就变成了删除叶子节点
		3.1、如果叶子节点是红色,对应情况1,直接删除
		3.2、如果叶子节点是黑色,对应情况2,进行后续处理
	4、删除节点有两个子节点
		将当前节点和后续节点中的一个节点值进行交换,改为删除叶子节点
		4.1、没有叶子节点
			对应情况1、2
		4.2、有一个叶子节点
			对应情况3
		4.2、有两个叶子节点
			对应情况4
	经过上述步骤的转换,将情况转换为删除叶子节点,其中叶子节点为红色的已经处理过,现在只需要考虑,
删除叶子节点为黑色的情况
	5、删除的叶子节点为黑色
		5.1、删除节点的兄弟节点为红色
			删除节点为左节点:
				将父节点和兄弟节点颜色互换,对父节点进行左旋
			删除节点为右节点:
				将父节点和兄弟节点颜色互换,对父节点进行右旋
		5.2、删除节点兄弟节点为黑色,远侄子节点为红色
			删除节点为左节点:
				这时删除节点的远侄子节点为兄弟节点的右节点
				将父节点和兄弟节点颜色对调,并把远侄子节点变成黑色,对父节点进行左旋
				删除当前需要删除的节点
			删除节点为右节点:
				这时删除节点的远侄子节点为兄弟节点的左节点
				将父节点和兄弟节点颜色对调,并把远侄子节点变成黑色,对父节点进行右旋
				删除当前需要删除的节点
		5.3、删除节点兄弟节点是黑色,远侄子节点是红色
			删除节点为左节点:
				近侄子节点和兄弟节点颜色互换,并将近侄子节点进行右旋
				这时候就变成了5.2情况
			删除节点为右节点:
				近侄子节点和兄弟节点颜色互换,将近侄子节点进行左旋
				这时候就变成了5.2情况
		5.4、父节点是红色,兄弟节点和兄弟节点的两个孩子(只能是空节点)都是黑色的情况
			将父节点变成黑色,兄弟节点变成红色
			删除当前节点
		5.5、父节点和兄弟节点及兄弟节点的两个子节点,都是黑色
			将兄弟节点变成红色,删除节点
			这样删除节点后,父节点的左右两个黑色节点数就相等了,但是经过祖父节点的路径黑色节点
			的数就少1个,这个时候,我们再以父节点为起始节点(不用删除节点了),继续根据情况进行
			平衡操作,在看是哪种情况,在进行对应的调整,这样一直向上,直到新的起始节点为根节点


示例:

初始红黑树结构如下图所示:
在这里插入图片描述
假如需要删除数字4,经过判断,满足 5.5、父节点(数字3)和兄弟节点(数字2)及兄弟节点的两个子节点(空节点),都是黑色,将兄弟节点(数字2)变成红色,并删除当前节点(数字4),如下图所示:
在这里插入图片描述
这时以父节点(数字3)为当前节点进行后续操作(不在删除数据),经过判断,满足5.2、删除节点兄弟节点为黑色,远侄子节点为红色,并且删除节点为左节点,将父节点(数字9)和兄弟节点(数字14)颜色对调,并把远侄子节点(数字18)变成黑色,对父节点(数字9)进行左旋,如下图所示:
在这里插入图片描述
至此,删除节点(数字4)流程完毕

3. 红黑树修改&查找节点过程

修改和查找节点过程相同,列举查找过程
1、以根节点进行和查找值进行对比
	1.1、等于当前值
		直接返回
	1.2、小于当前值
		以左节点为当前节点进行对比,重复情况1
	1.3、大于当前值
		以右节点为当前节点进行对比,重复情况1
2、当遍历到叶子节点,而且没有找到对应的值,则返回空
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
红黑树是一种自平衡的二叉搜索树,它具有以下特性: 1. 每个节点要么是红色,要么是黑色。 2. 根节点是黑色的。 3. 每个叶子节点(NIL节点,空节点)是黑色的。 4. 如果一个节点是红色的,则它的两个子节点都是黑色的。 5. 对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。 下面是红黑树删除节点的示例代码: ```cpp // 定义红黑树节点结构 struct Node { int data; bool isRed; Node* left; Node* right; Node* parent; }; // 红黑树删除节点函数 void deleteNode(Node*& root, int key) { // 查找要删除节点 Node* node = search(root, key); if (node == nullptr) { return; } // 执行删除操作 if (node->left != nullptr && node->right != nullptr) { // 被删除节点有两个子节点 Node* successor = findSuccessor(node); node->data = successor->data; node = successor; } // 被删除节点最多只有一个子节点 Node* child = (node->left != nullptr) ? node->left : node->right; if (node->isRed) { // 被删除节点为红色,直接删除 if (node->parent->left == node) { node->parent->left = child; } else { node->parent->right = child; } if (child != nullptr) { child->parent = node->parent; } delete node; } else if (child != nullptr && child->isRed) { // 被删除节点为黑色,子节点为红色,直接替换并染黑 child->isRed = false; if (node->parent->left == node) { node->parent->left = child; } else { node->parent->right = child; } child->parent = node->parent; delete node; } else { // 被删除节点为黑色,子节点为黑色或空节点,需要进行调整 deleteCase1(root, node); if (node->parent != nullptr) { if (node->parent->left == node) { node->parent->left = nullptr; } else { node->parent->right = nullptr; } } delete node; } } // 其他辅助函数和删除情况的处理函数省略... ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值