红黑树定义
- 每个节点要么红要么黑
- 根节点是黑色
- 每个叶子节点都是黑色(叶子是NULL节点表示 或 NIL节点表示)。
- 如果一个节点是红色的,那么它的子节点必须是黑色的子节点。(即不存在两个连续的红色节点)
- 从任一节点到其每个叶子结点(NULL节点或 NIL节点)的所有简单路径都包含相同数目的黑色节点。
红黑树的删除算法分析
- 【约定一:删除的节点有两个儿子,可以转换只有一个儿子的节点或没有儿子的结点】。为了将删除问题尽可能的简化,我们需要将删除的情况尽可能统一。这里我们讨论删除简化。
后继结点概念
如图,我们要寻找节点(7)的后继节点,如何查找。按照前序遍历算法:1. 左孩子;2. 节点;3. 右孩子,遍历结果为:6 7 8 10 11
,即:节点7的后驱为8,也就是去寻找该节点以右孩子为子树的最小节点。
删除节点转换举例,假设下列两种情况,我们都是删除节点7
步骤一,后继节点查找,该节点右子树中的最小元素(图中为值8的节点)
步骤二,把后继结点值(8)转移到要删除的节点中
步骤三,转换为删除图中背景为黄色结点
通过上述转换,我们可以得出结论,删除节点只有一个儿子的节点或没有儿子的结点
- 【约定二:调整需要旋转+节点变换颜色】。当出现两个出现两个连续红色节点,则不满足红黑树性质,需要使用两种手法调整结点颜色或位置,来保持树满足红黑树
节点变换颜色算法
变化颜色比较简单,红->黑、黑->红、指定某一个结点为黑、指定某一个结点为红。共四种情况
旋转算法
旋转算法包括左旋和右旋,两种属于镜像对称实现。旋转都是调整结点的位置
左旋
- x右孩子指向y的左孩子
- y的左孩子指向x
右旋
- y左孩子指向x的右孩子
- x的右孩子指向y
- 【约定三:哪些情况需要调整】。由约定一可知,删除只需要讨论删除节点只有一个儿子的节点或没有儿子的结点情况,整理了以下5中情况
- 情况1,删除黑色节点N,会影响红黑树性质5,将红色孩子节点变黑。
- 情况2,删除黑色节点N,会影响红黑树性质5,需要调整
- 情况3,删除红色节点N,没影响
- 情况4,删除没有儿子的结点,当做情况3处理
- 情况5,删除没有儿子的结点,当做情况2处理
总结,经过上述分析,我们可以得出,需要调整的情况是:删除的节点和它的儿子都是黑色
红黑树的删除调整CaseA分析
- 删除节点S,R为它的孩子,删除后,R顶替S的位置,将节点命令为N(黑色),CASEA作为左孩子情况
接下来,我们将讨论P/S/SL/SR不同颜色时,如何调整
CaseA1:S红色
由于S为红色,可以推断出P/SL/SR都为黑色(红黑树性质4)
调整策略
- P节点设置红色
- S节点设置黑色
- P节点为支点左旋
CaseA2:S黑色,SL黑色,SR黑色,P任意
调整策略
- P节点设置黑色
- S节点设置红色
- 设置P点为当前节点,继续执行删除逻辑判断
CaseA3:S黑色,SL红色,SR黑色,P任意
调整策略
- SL节点设置黑色
- S节点设置红色
- S节点为支点右旋
CaseA4:S黑色,SL黑色,SR红色,P任意
调整策略
- SR节点设置黑色
- S节点设置P节点颜色
- P节点设置黑色
- P节点为支点左旋
红黑树的删除调整CaseB分析
- 删除节点S,R为它的孩子,删除后,R顶替S的位置,将节点命令为N(黑色),CASEB作为右孩子情况,情况与CASEA镜面对称
接下来,我们将讨论P/S/SL/SR不同颜色时,如何调整
CaseB1:S红色
由于S为红色,可以推断出P/SL/SR都为黑色(红黑树性质4)
调整策略
- P节点设置红色
- S节点设置黑色
- P节点为支点右旋
CaseB2:S黑色,SL黑色,SR黑色,P任意
调整策略
- P节点设置黑色
- S节点设置红色
- 设置P点为当前节点,继续执行删除逻辑判断
CaseB3:S黑色,SL黑色,SR红色,P任意
调整策略
- SR节点设置黑色
- S节点设置红色
- S节点为支点左旋
CaseB4:S黑色,SL红色,SR黑色,P任意
调整策略
- SL节点设置黑色
- S节点设置P节点颜色
- P节点设置黑色
- P节点为支点右旋