红黑树的增加(插入)和删除

Posted 一乐乐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树的增加(插入)和删除相关的知识,希望对你有一定的参考价值。

红黑树的增加(插入)和删除

 

☼ 红黑树之介绍:

-----------形态上是特殊的二叉搜索树【特殊体现在颜色上,同时在逻辑上它是等价于4阶B树的】

 

❀ 红黑树是怎么等价于4 阶B 树的? ---------红黑树要变成B树:需要将红结点和黑结点进行合并(黑色作为根【也是中间元素】)。

红黑-->B 树: 结点有四种情况是:①红-黑-红、②红-黑、③黑-红、④黑

 

● 可以插入的位置的所有情况:

◼ 红黑树必须满足以下 5 条性质:

1. 节点是 RED 或者 BLACK

2. 根节点是 BLACK

3. 叶子节点(外部节点,空节点)都是 BLACK

4. RED 节点的子节点都是 BLACK:

✓ RED 节点的 parent 都是 BLACK

✓ 从根节点到叶子节点的所有路径上不能有 2 个连续的 RED 节点

5. 从任一节点到叶子节点的所有路径都包含相同数目的 BLACK 节点

 

一、红黑树结点的添加(插入)--添加必是添加到 -B树叶子子结点的位置:

(1) 4阶 B 树的叶子结点一般有以下四种情况:

①    红<---黑--->红    ② 红<---        ③ --->红      ④

(2) 分类讨论:

(2-1)当父结点是黑色(有四种情况)时【上图的 7、8、11、12】,直接插入;【有可能是第一个结点-根(记得染黑根)】;

(2-2)剩下8种情况根据 叔父结点是否为红色进行划分:

(2-2-1)叔父是红色时【上图的 1、2、3、4】,举个栗子:   (新插入的)<---<---【根】--->红 (对于4阶B树而言,发生了上溢了,需要,进行分裂处理根(染红)上去,然后父结点、叔父结点染黑);即 :

 

 (2-2-2)叔父不是红色时【上图的 5、6、9、10】,举个栗子:   (新插入的)<---<---【根】:为了满足红黑树定义的性质四:

   (新插入的)<---红(变黑)<---【根】(变红因为B树的结点组合中是红黑红(只有一个黑作为中间元素的根)

  ●  现在需要修改:中间的黑色为根,需要修改那个<---的方向:改为:

  (新插入的)<---红(变黑) 【根】--->【根】(变红)

[观察此刻情况,修改这种修改,符合右旋,再观察其实就是跟AVL 的LL型原理一致啦]

 

❀ 红黑树整个添加之后的处理的代码如下:

    @Override
    protected void afterAdd(Node<E> node) {
        // 判断父结点
        Node<E> parent = node.parent;
        // 添加的是根【当添加第一个结点时】/ 或者上溢到了根结点时
        if (parent == null) {
            black(node);
            return;
        }
        // 若父结点是黑色时,不用处理,直接返回
        if (isBlack(parent))
            return;

        // 若叔父结点是红色的[B 树的上溢]
        Node<E> uncle = parent.sibling();
        Node<E> grand = red(parent.parent);
        if (isRed(uncle)) {
            // 染黑爸爸、叔叔,把祖父染成红色,相当于新插入的结点
            black(uncle);
            black(parent);
//            red(grand);
//            afterAdd(grand);
            // ① 上溢时,也要染红祖父结点
//            afterAdd(red(grand));
            afterAdd(grand);
            return;
        }
        //观察一下,对代码进行优化,共同拥有的抽到外部之类的
        // 来到这里叔父不是红色
        if (parent.isLeftChild()) { // L
            // ② 旋转时,也要 染红结点
//            red(grand);
            
            if (node.isLeftChild()) { // LL
                //染黑父结点,染红祖父结点
                black(parent);
//                red(grand);
                //右旋
//                rotateRight(grand);
            } else { // LR
                //染红自己、染黑祖父结点
                black(node);
//                red(grand);
                //左旋后右旋
                rotateLeft(parent);
//                rotateRight(grand);
            }
            
            rotateRight(grand);
        } else { // R
            // ② 旋转时,也要 染红结点
//            red(grand);
            
            if (node.isLeftChild()) { // RL
                //染红自己、染黑祖父结点
                black(node);
//                red(grand);
                //左旋后右旋
                rotateRight(parent);
//                rotateLeft(grand);
            } else { // RR
                //染黑父结点,染红祖父结点
                black(parent);
//                red(grand);
                //左旋
//                rotateLeft(grand);
            }
            
            rotateLeft(grand);
        }
    }

 

二、红黑树结点的删除--删除必是 -B树叶子子结点的位置:

● 可以删除的位置的所有情况:

(1) 4阶 B 树的叶子结点一般有以下四种情况:

①    红<---黑--->红    ② 红<---        ③ --->红      ④

(2) 分类讨论:

(2-1) 删除的直接是红色结点时【上图的 1、3、5、6】【2也一样(因为它是度为2,最终删除的要么是前驱的1或者后驱的3)就直接删除,不用处理。

(2-2) 删除的是黑色的结点:

(2-2-1)用来替代的结点是红色时【上图的 4、7】处理:将替代的结点【5、6】染成黑色(因为替代成为了B树的叶子结点了,根是黑色的)。

 (2-2-2)用来替代的结点是黑色时【上图的 8】,处理:

 

 

 

 

红黑树的插入与删除

红黑树(Red Black Tree) 是一种自平衡二叉查找树。红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。红黑树可以在O(log n)时间内完成查找,插入和删除操作。
二叉搜索树可以看 二叉搜索树
AVL树可以看 AVL树的插入与删除

1. 红黑树的性质

红黑树的自平衡依赖于它的以下性质:

性质1. 结点是红色或黑色。

以上是关于红黑树的增加(插入)和删除的主要内容,如果未能解决你的问题,请参考以下文章

C++-红黑树的插入和删除实现

红黑树的插入与删除

红黑树插入与删除完整代码(dart语言实现)

数据结构之红黑树

如何轻松记住红黑树的插入和删除?

红黑树数据结构剖析