性质:
不存在连续相同的红节点头节点为黑色
所有路径的黑色节点个数相同
空节点为黑色
关于插入:
规定每新插入一个节点默认为红色(也可以是黑色,但没必要)如果其parent节点是黑色不需要处理
如果是红色,需要向其uncle节点把红节点分散开
所以分两种情况
1.uncle为红色
分析:
如果uncle是红色,则已经不能把这边多的红色节点传过去了
则把parent跟uncle变成黑色,grandparent变成红色即可
需要注意的是,grandparent上面的父节点也可能是红色,需要继续处理2.uncle为黑色
则可以通过旋转处理并改色
2.1如果cur在parent的左边
2.2如果cur在parent的右边
先parent进行左旋,再整体右旋即可
上面的情况是parent在grandparent的左边的情况,右边完全类似
ps:
头结点可能在插入调整的过程中变为红色,所以需要在完成上面操作后将其变黑
关于删除
删除的情况:
1.删除节点有两个子节点2.删除节点有一个子节点
3.删除节点没有子节点
第1种情况可以通过替换法转换成下面两种情况,而第三种情况我们可以看做第二种情况,
即有一个子节点,但这个子节点为空(另一个子节点不用管)
所以总的来说,我们只需要处理只有一个子节点的情况
大方向分为两个
1.删除节点在其父节点的左边
2.删除节点在其父节点的右边
这里只说明第一种,另一个完全类似
考虑到可能有人对上面说的删除节点的子节点的说明有点困惑
这里说明一下
显然如果都为空,也不影响上面的链接操作
不管怎么样,在删除后都可以变成右边的情况
如果上面的理解的话
那么接下来要开始进行调色来保证其仍是一个二叉树
情况分为下面几种
1.如果删除节点是红色
根据红黑树性质的约束
只可能是下面的一种情况
直接删除即可
2.如果删除节点是黑色
情况又分为两种
2.1如果DR为红色
分析:
DR的两个子节点必为空,否则不满足性质删除后
将DR改成黑色即可
2.2
如果DR为黑色(则DR必为空)
那我们需要考虑根据隔壁的brother的颜色进行调整
2.2.1
如果brother黑色红色
处理方式:
将parent进行左旋,然后brother改成parent的颜色parent改成红色
处理后的DR路径仍然少一个黑色节点,但此时已经转化成了DR隔壁的节点为黑色的情况
按下面说的某种情况来处理来处理就行了
2.2.2
如果brother为黑色
分为4种情况
情况1:
brother_left为红色,brother_right为任意色
处理方式:
将brother进行右旋,在将parent进行左旋,然后brother_left改成parent的颜色