红黑树颜色规则
- 节点不是黑色,就是红色(非黑即红);
- 根节点一定为黑色;
- 叶子节点为黑色是NULL节点,且颜色为黑色;
- 根到叶子的所有路径,不可能存在两个连续的红色节点,也就是说如果一个节点为红色,则其两个子节点必须是黑色;
- 每个节点到叶子节点的所有路径,都包含相同数目的黑色节点(相同的黑色高度);
红黑树的删除
1.删除结点没有儿子
1.1 删除结点为红色—直接删除
例如:下图中删除130:
- 因为删除的是红色结点,不会影响红黑树第5条性质,所以可以直接删除
1.2 删除结点为黑色,其兄弟结点没有儿子
- 在这种情况下,如果要成为一个红黑树,必须满足兄弟节点也一定是黑色的;
- 在上图的情况下,如果我们要删除150这个节点,直接删除是一定不满足第五点要求的;
- 此时,我们要把150的父节点140变成黑色,然后把150的兄弟节点126变成红色:
- 此时满足第五点,成为一个红黑色!
1.3 删除结点为黑色,其兄弟结点有一个孩子不空,并且该孩子和兄弟结点在同一边(同为左子树或者同为右子树)
- 在上图的情况下,如果我们要删除110这个节点,直接删除是一定不满足第五点要求的;
- 此时,110的兄弟节点140有孩子150,并且和兄弟节点相同都为右孩子;
- 先删除150,然后交换兄弟节点140和父节点120的颜色,然后把兄弟节点的孩子变成黑色,即140,120,150都为黑色;
- 如果兄弟结点和兄弟结点的儿子都在右子树的话:对父亲结点进行左旋;如果兄弟结点和兄弟结点的儿子都在左子树的话:对父亲结点进行右旋;所以我们现在还需要对节点120进行左旋:
左旋转示意图如下:
结果如下图:
1.4 删除结点为黑色,其兄弟结点有一个孩子不空,并且该孩子和兄弟结点不在同一边(右左或者左右的情况)
- 假设要删除的结点是80,其兄弟结点30只有一个儿子50,而且兄弟结点为左结点,兄弟结点的儿子为右结点;
- 先将需要删除的80结点删除,然后将兄弟结点和兄弟结点的儿子结点颜色互换,即30变为红色,50变为黑色:
- 如果兄弟结点是左子树,兄弟结点的儿子结点是右子树:对兄弟结点进行左旋;如果兄弟结点是右子树,兄弟结点的儿子结点是左子树:对兄弟结点进行右旋。上图是左右,所以接下来对兄弟结点30进行左旋,结果如下图:
- 此时,红黑树情况和情况1.3中的情况很相似,兄弟结点50和兄弟结点的子节点30处在同一边,我们可以按照情况1.3的处理办法进行处理:
- 交换兄弟节点50和父节点60的颜色,并把兄弟节点的孩子变成黑色,即30,50,60都为黑色:
- 兄弟节点和其子节点都为左子树,对父节点60进行右旋,右旋示意图如下:
- 结果如下:
1.5 删除结点为黑色,其兄弟结点有两个孩子,兄弟结点为黑色而且两个孩子结点也为黑色
删除130
- 首先删除130,然后将父亲结点140和兄弟结点150颜色互换;
1.6 删除结点为黑色,其兄弟结点有两个孩子,而且兄弟结点为红色
删除110
- 先交换兄弟结点140和父亲结点120的颜色
- 被删除的元素为左子树:对父亲结点左旋;
- 被删除的元素为右子树:对父亲结点右旋;
- 对140进行左旋
- 此时和情况1.5类似,删除结点110为黑色,其兄弟结点130有两个孩子,兄弟结点为黑色而且两个孩子结点也为黑色;
- 先删除110,然后将父亲结点120和兄弟结点130颜色互换;
总结:删除结点没有儿子结点的情况(空叶子结点不算儿子结点)
- 删除结点为红色:直接删除
- 删除结点为黑色,其兄弟结点没有儿子:兄弟结点变红,父亲结点变黑,然后将父亲结点当作当前结点按照这几种情形处理,直到当前结点为根结点
- 删除结点为黑色,其兄弟结点有一个孩子不空,并且该孩子和兄弟结点在同一边(同为左子树或者同为右子树):
- 先交换兄弟结点和父亲结点的颜色,并且把父亲结点和兄弟结点的子结点涂成黑色
- 如果兄弟结点和兄弟结点的儿子都在右子树的话:对父亲结点进行左旋
- 如果兄弟结点和兄弟结点的儿子都在左子树的话:对父亲结点进行右旋
- 删除结点为黑色,其兄弟结点有一个孩子不空,并且该孩子和兄弟结点不在同一边(右左或者左右的情况):
- 先将兄弟结点和兄弟结点的儿子结点颜色互换
- 如果兄弟结点是左子树,兄弟结点的儿子结点是右子树:对兄弟结点进行左旋
- 如果兄弟结点是右子树,兄弟结点的儿子结点是左子树:对兄弟结点进行右旋
- 将后续变换按照第3条处理
- 删除结点为黑色,其兄弟结点有两个孩子,兄弟结点为黑色而且两个孩子结点也为黑色:
- 将父亲结点和兄弟结点颜色互换
- 删除结点为黑色,其兄弟结点有两个孩子,而且兄弟结点为红色:
- 将兄弟结点和父亲结点的颜色互换
- 被删除的元素为左子树:对父亲结点左旋
- 被删除的元素为右子树:对父亲结点右旋
- 将后续变换按照第5条进行处理
2. 删除结点仅有一个儿子结点的情况
2.1 删除结点为黑色,儿子结点无论左右都可以
删除120
- 将120删除,然后将子节点130变成黑色放到被删除结点120的位置,结果如下:
2.2 删除结点为红色:其儿子结点只能为黑–直接删除
总结删除结点只有一个儿子的情况:
- 删除结点为黑色,儿子结点无论左右都可以:将儿子结点变成黑色放到被删除结点的位置;
- 删除结点为红色:其儿子结点只能为黑–直接删除
3. 删除结点有两个儿子结点
删除120:
- 找到结点120右子树中最左的结点125,交换两者的值,图如下:
- 删除结点120没有一个儿子,而且其兄弟结点也没有儿子,即删除结点为黑色,其兄弟结点没有儿子;
- 兄弟结点127变为红色,父亲结点125变黑