摘要
插入2种情况,删除(调平衡)5种情况
红黑树
性质
-
性质1:每个节点要么是黑色,要么是红色。
-
性质2:根节点是黑色。
-
性质3:每个叶子节点(NIL)是黑色。这里说的叶子节点是Null节点
-
性质4:每个红色结点的两个子结点一定都是黑色。
-
性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。(黑色完美平衡。)
-
性质5.1:如果一个结点存在黑子结点,那么该结点肯定有两个子结点
红黑树插入
插入红色还是插入黑色呢?
思考:插入红色可能会违反性质4(两个红色不能相连),插入黑色一定会违反性质5(黑色完美平衡),我们的选择是插入红色,因为插入黑色违反性质5后还得变色,变色后有可能违反性质4,所以性质4插入黑色也可能违反,所以插入黑色可能会违反性质4和性质5,所以我们选择插入红色。
答:插入红色,即新节点是红色的
为什么叶子节点是Null节点,而不是左右孩子为null的节点
我也不知道为啥,我感觉这个定义无所谓,不加这一条性质也行(性质3)
插入大概步骤:
先找到父节点,根据插入分类进行插入。
插入分类:
这里旋转不细讲,只说一下重点,第一:将三个节点中val是中间值的节点转到顶部(祖父位置)(这一点定义了旋转的目标)。第二:旋转过程中需要保持搜索树的性质(这一点定义了孩子如何转到父亲,左旋还是右旋)。更详细可以看此文。
a.红黑树为空树:
- 直接插入,并将根节点改为黑色。
b.插入节点的父节点为黑色:
- 直接插入(消除一个黑色节点,在添加一个红色节点,和一层黑色节点,一定不会违反黑色完美平衡)
c.插入节点的父节点为红色
此情此景,父节点一定不是根(性质一)。
ca.叔叔结点不存在或为黑结点(黑红红->黑红)(最简单的旋转)
- 将P设为黑色
- 将PP设为红色
- 对P旋转到PP位置
cb.叔叔节点为红色(黑红红->红黑红,当前的节点为祖父节点,递归进行旋转变色,如果祖父节点是根节点,再变回黑色,这也是唯一一种会增加红黑树黑色结点层数的插入情景)(不能进行最简单的旋转,因为叔叔,父亲变黑,祖父变红,祖父和叔叔还是红红连线,如果再将叔叔变黑,这不是多此一举吗,明明只变色就行,为什么要又变色又旋转的)
-
将P和S设置为黑色
-
将PP设置为红色
-
把PP设置为当前插入结点
红黑树删除
二叉搜索树删除大概步骤:
1.找到待删除的后继结点替换待删除结点
2.删除后继节点
3.红黑树和二叉搜索树的删除类似,只不过加上颜色属性(这里的子节点均属非NULL节点):
红黑树删除步骤:
1.无子节点
-
直接删除
-
如果节点为黑色,黑色数目减1,需要进行平衡的操作
2.只有一个子节点,删除节点为黑色,其子节点为红色(性质一,黑色完美平衡)
- 用子节点代替删除节点(颜色涂黑),删除子节点。
3.有两个子节点
- 使用后继节点代替的删除节点,递归删除后继节点。
祥解删除黑色子节点后的平衡(情况1)(祥解调平衡)
**删除前的思考:**黑色叶子要么是根,要么黑色叶子节点是一定有兄弟的,兄弟有可能是黑色叶子,也有可能兄弟是一棵红色的数。第一次失衡发生在删除黑色叶子之后,此时失衡节点是删除的黑色叶子的父亲,黑色叶子成了NULL节点,所以当前节点是NULL节点,不再是被删除的黑色叶子。所有的平衡思路都是尝试给我的黑色节点加一,或者兄弟的黑色减一(在递归)
1.删除节点为根节点
- 直接删除
2.兄弟节点为黑色
2.1.兄弟的子节点全黑
2.1.1.父节点为黑色 (兄弟减一,在递归)
● 将兄弟节点涂红(此时父亲节点黑色平衡(黑色路径减一),祖父节点黑色失衡)
● 将父点标记为当前节点,递归进行
2.1.2.父节点为红色(兄弟减一,父亲加一,结束)
● 兄弟节点涂红,父节点涂黑,平衡结束。
2.2.兄弟的子节点不全黑(包括一黑一红和两红)
2.2.1 兄弟的对位孩子为红色(我是左节点对位就是右节点)(通过旋转(父亲下来)我加一,父,兄弟上去兄弟减一,兄弟孩子改颜色加一,结束)
● 兄弟旋转到父亲,颜色也改为父亲的颜色
● 将父亲改为黑色(这样我这一枝黑色路径加一)
● 对位孩子改成黑色(原本是红色的改为黑色,路径加一,由于少了兄弟这一黑色,所以总路径不变)
2.2.2 兄弟的对位孩子为黑色,另一个肯定是红色(旋转到对位是红色)
● 将对位孩子转到兄弟位置
● 互换兄弟和对位孩子的颜色(其实,就是凑2.2.1)
● 进行2.2.1的转换(颜色互换,总路径不变)
3.兄弟节点为红色(不破坏路径,旋转到兄弟是黑色处理)
● 兄弟节点旋转到父亲
● 兄弟节点变成黑色
● 父节点变红色
看完删除感觉插入好简单
插入2种情况,删除(调平衡)5种情况