红黑树的5个性质:
- 性质1. 节点是红色或黑色。
- 性质2. 根节点是黑色。
- 性质3.所有叶子都是黑色。(叶子是NUIL节点)
- 性质4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
- 性质5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
节点名称规定:
删除节点为D
D的父亲节点为P
D的兄弟节点为B
D的侄子节点为N
D的左侄子节点为LN
D的右侄子节点为RN
D的左孩子为LC
D的右孩子为RC
1.由红黑树的5个性质,当下面一层为叶子节点时,可以得出两层的红黑树的结构只能是一下5种。
2.删除节点时,根据节点的位置,分为4种情况。
情况1:删除节点为叶子节点。
情况2:删除节点只有左孩子,没有右孩子。
情况3:删除节点只有右孩子,没有左孩子。
情况4:删除节点既有左孩子,又有右孩子。
情况1:删除节点为叶子节点。
1.1 如果删除叶子节点D为红色节点。操作:直接删除节点D。
1.2 如果删除叶子节点D为黑色节点。
当节点D的兄弟节点B为黑色时,P为红色或者黑色都可以,这里P用白色圆圈表示,虚线方框内有4种情况(1)(2)(3)(4)。当节点D的兄弟节点B为红色时,P为黑色,虚线方框内只有一种情况(5)。下面讨论的是要删除的叶子结点D为节点P的左孩子。要删除的叶子结点D为节点P的右孩子,和是左孩子的分析是一样的,是对称的。这里不再重复描述。
假设左边黑色节点为要删除的叶子结点D,则一共有5种情况。如下图所示。因为左边支路上有一个黑色节点。所以右边支路上也要有一个黑色节点。
1.2.1 要删除的叶子结点D为黑色,D的兄弟节点B也为黑色。没有侄子节点。
操作:1)先将D节点删除。 2)将P节点变成黑色,将B节点变成红色。
1.2.2 要删除的叶子结点D为黑色,D的兄弟节点B也为黑色。D的左侄子为红色。
操作:1)先将D节点删除。 2)再将B——LN进行右旋。 3)然后将LN变成P的颜色,P节点变成黑色。 4)将P——LN——B,进行左旋。
1.2.3 要删除的叶子结点D为黑色,D的兄弟节点B也为黑色。D的右侄子为红色。
操作:1)先将D节点删除。 2)B变成P的颜色。P和RN变成黑色。 3)将P——B——RN进行左旋操作。
1.2.4 要删除的叶子结点D为黑色,D的兄弟节点B也为黑色。D的左侄子和右侄子都为红色。
操作:1)先将D节点删除。 2)将P——B——RN进行左旋操作。 3)将B变成P的颜色,P和RN变成黑色。
1.2.5 要删除的叶子结点D为黑色,D的兄弟节点B为红色。D的左侄子和右侄子都为黑色。
操作:1)先将D节点删除。 2)将P——B——RN左旋 3)将B变成黑色,LN变成红色。
情况2:删除节点只有左孩子,没有右孩子。只能是如下图所示。
操作:1)将D的值变成LC的值, 2)删除LC节点。
情况3:删除节点D只有右孩子,没有左孩子。和情况2一样。只能如下图所示。
操作:1)将D的值变成LC的值。 2)删除LC节点。
情况4:删除节点D既有左孩子,又有右孩子。
操作:1)将D节点的值替换成D节点前驱节点的值 2)然后删除前驱节点。此时可以转换成前3种情况。
总结:
1.如果删除节点D有左右孩子,将删除节点的值替换为删除节点前驱节点的值,然后再删除前驱结点。删除前驱结点的操作更简单。
2.如果删除节点D只有左孩子LC,没有右孩子。将D的值替换成LC的值,然后将LC删除。
3.如果删除节点D只有右孩子RC,没有左孩子。将D的值替换成RC的值,然后将RC删除。
4.如果删除节点D是叶子结点,且为红色。直接删除。
5.如果删除节点D是叶子节点,为黑色。
1)如果兄弟节点B为黑色,也为叶子结点。删除节点D,父亲节点P变成黑色,B节点变成红色。
2)如果兄弟节点B为黑色,不为叶子结点,如下图,有(1),(2),(3)种情况。删除节点D,然后进行旋转。旋转后前三个节点的颜色和旋转前 前三个节点对应的颜色相同。删除后如果有第四个节点,第四个节点为红色。(这是自己总结的,可能不对)
3)如果兄弟节点为红色,则删除节点D,然后进行旋转操作。最后,前三个节点为黑色,最后一个节点为红色。