红黑树节点插入

本来打算一下写完的,图太多了,自己都没耐心看完,就把插入和删除分开写了。

红黑树有5个性质
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质4. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
性质5.每个叶节点是黑色的。

性质5是一本书里额外添加的,本来只有前4个性质,性质5的作用是为了测试红黑树的性质4我简单借张图片表示,看到那些NIL了吗,他们就是性质5的叶节点,也是性质4的测试方法
在这里插入图片描述

这几个性质记好了,我们就直接开始建造树,然后便建造便分析各种情况。
先总结各种情况,一会你看完下面例子在扭头看总结也可以
父亲节点为黑直接加入即可
父亲叔叔节点为红,将爷爷变红,父亲叔叔变黑直接加入
父亲为红叔叔为黑,分2种情况
1,父亲为左子树自己也是左子树或者父亲为右子树自己也为右子树,父亲变黑爷爷变红,自己为左子树右旋转,自己为右子树左旋转
2父亲为左子树自己是右子树或者父亲为右子树自己也为左子树,先和父亲替换下位置然后以父亲为新加入的节点进行变化

我们先随便选择一组数字吧(前面数字我随便选的,后面为了满足各种插入时的情况就特意选择的)
77,66,88,21,3,5,99,1024,7,1,89,2

插入规则为二叉树的插入
二叉查找树的插入很简单,先把要插入的节点的key与根进行比较,小则和根的左孩子做比较,大则跟右孩子作比较,直到找到叶子节点。

第一步,我们把77作为根结点
根结点必须为黑色

在这里插入图片描述

第二步,66和88两个子节点的插入
这里引出一个规则,红黑树除了根结点的所有结点插入时颜色默认为红色,原因,性质4. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点,插入一个黑色节点就会违反这个规则。
在这里插入图片描述

第3步,21的插入
这个插入引出了插入的一个性质,叔叔和父亲都是红色
在这里我们要是直接插入便会违法性质3红树的节点必须是黑色,要是把21直接插入便会违法性质4
在这里插入图片描述

这种情况,也就是父亲节点和叔叔节点都是红色的,我们这样解决,把父亲和叔叔便黑,爷爷变红(如果爷爷为根节点则不需要改变颜色)
在这里插入图片描述
因为爷爷为根结点,所以变黑
在这里插入图片描述
第4部插入3
在这里插入图片描述
这里有一个问题我们平时插入的时候是根据叔叔和父亲插入的,这里没有叔叔啊,其实是有的,你忘记性质5了,叔叔是黑色的(如下图)
在这里插入图片描述
这样叔叔是不是就很明显 了我们在回归怎么插入3这个问题
在这里插入图片描述父亲为红色,叔叔为黑色这种情况我们要进行旋转,旋转前要换颜色也就是把父亲变为黑色爷爷变为红色
在这里插入图片描述
然后进行右旋转
在这里插入图片描述旋转的过程中并不会引起红黑树的平衡,原因自己想去。
第五部插入5
父亲结点和叔叔结点都为红色,和前面方法一样父亲叔叔变黑,爷爷变红
在这里插入图片描述

在这里插入图片描述
红黑树平衡为影响(这一步可能会影响爷爷节点的平衡,所以在代码需要判断)
第6部99,父亲为黑,直接插入即可
在这里插入图片描述
第7部1024
在这里插入图片描述
父亲为红叔叔为黑,将父亲变黑爷爷变红,旋转
在这里插入图片描述
第8部7
在这里插入图片描述
父亲节点变黑,爷爷结点变红,旋转
在这里插入图片描述
到这里我们还有3种情况没有说,我们选择3个数说一下剩余的3种情况

我们先插入1
在这里插入图片描述
父亲节点和叔叔节点都是红色,父亲和叔叔变黑,爷爷变红
在这里插入图片描述5和21都是红色不符合规则
5的父亲节点为红色,叔叔节点为黑色,将5的父亲变黑爷爷变红
在这里插入图片描述从爷爷77进行旋转(旋转都是从爷爷转的)
在这里插入图片描述
插入1023
这步很有意思,靠仔细看了
在这里插入图片描述
父亲和叔叔为红,将爷爷变黑,父亲叔叔变黑
在这里插入图片描述
99的父亲和叔叔为红,同样道理,父亲叔叔变黑,爷爷变红
在这里插入图片描述
爷爷为根结点,所以爷爷变黑
在这里插入图片描述
2的插入
2的插入是最后一块了,这个一说关于红黑树的插入就结束了,剩下的就是比较简单的代码了,我明天有空就把代码打出来。
在这里插入图片描述
这种情况我们不能直接把1变黑,3变红,因为这种变法在多数情况下更容易起冲突,虽然这样做也并不违反红黑树的平衡
我们需要先左旋转,让1成为新插入的数
在这里插入图片描述然后父亲变黑(也就是2),爷爷变红,也就是3,进行一次旋转即可
在这里插入图片描述

困了,代码和删除明天在写,挺简单的,我感觉应该通俗易懂吧,另外你们想要什么样的代码可以私聊java,C/C++,C#,python,Scala,lua,Kotlin,go这些都可以,其他的看我会不会了,但是我有没有时间写就不一定了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值