红黑树(Red–black tree)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。它在1972年由鲁道夫·贝尔发明,被称为"对称二叉B树",它现代的名字源于Leo J. Guibas和Robert Sedgewick于1978年写的一篇论文。
R-B Tree 全称是 Red-Black Tree ,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。
红黑树的特点
- 1、节点是红色或黑色。
- 2、根是黑色。
- 3、所有叶子都是黑色(叶子是NIL节点)。
- 4、每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。)
- 5、从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
插入操作
我们在对红黑树进行插入操作时,我们一般总是插入的红色节点,因为这样可以在插入过程中尽量避免对树的调整。那么,我们在插入一个节点后,可能会使原树一些特性发生改变:
如果我们插入的节点是根节点,性质 2 会被破坏,如果插入节点的父节点是红色,则会破坏性质 4。因此,总而言之,我们插入一个红色的节点只会破坏性质 2 和性质 4。
既然我们插入节点时会有破坏红黑树的特性,那么就有恢复红黑树特性的策略,插入节点恢复特性策略操作分如下几种情况:
情况一:插入的是根节点
问题:原树是空树,此情况只会破坏性质 2。
对策:直接把此节点涂为黑色。
情况二:插入节点的父节点是黑色
问题:此操作不会违反红黑树的特性,红黑树没有被破坏。
对策:什么都不做。
情况三:当前节点的父节点是红色且祖父节点的另一个子节点(叔叔节点)是红色
问题:此时父节点的父节点一定存在,否则插入前就已不是红黑树。与此同时,又分为父节点是祖父节点的左子树还是右子树,对于对称性,我们只要解开一个方向就可以了。在此,我们只考虑父节点为祖父节点的左子树情况。同时,还可以分为当前节点是其父节点的左子树还是右子树,但是两者的处理方式一样,我们将此归为同一类。
对策:将当前节点的父节点和叔叔节点涂黑,祖父节点涂红,把当前节点指向祖父节点,从新的当前节点开始算法。
针对情况三,变化前【当前节点为 25 节点】:
变化后:
情况四:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子树
对策:当前节点的父节点做为新的当前节点,以新的当前节点为支点左旋。
如下图所示:变化前【当前节点为 35 节点】
变化后:
情况五:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左子树
**策略:**父节点变为黑色,祖父节点变为红色,在祖父节点为支点右旋
如下图所示:【当前节点为 20 节点】
变化后:
总结:
经过上面情况三、情况四、情况五等三种插入恢复情况的操作示意图,我们就会发现,后面的情况四、情况五、都是针对情况三插入节点 25 以后,进行的一系列插入恢复情况操作,不过,指向当前节点 N 指针一直在变化。所以,我们可以理解为,整合下来,情况三、情况四、情况五就是一个完整的插入恢复情况的操作流程。
参考文献维基百科 – 红黑树:https://zh.wikipedia.org/wiki/红黑树