Day15 红黑树
uwupu 啦啦啦啦啦

红黑树

https://www.jianshu.com/p/4cd37000f4e3

https://www.bilibili.com/video/BV1Ce4y1Q76H

image

引入

有了二叉搜索树,为什么需要平衡二叉树?

  • 二叉搜索树容易变成链表,查找的时间复杂度就会从O(log2N)变为O(N)。
  • 引入平衡二叉树,防止树退化。

有了平衡二叉树,为什么还需要红黑树

  • 平衡二叉树插入删除操作影响效率
  • 红黑树减少插入/删除操作,整体性能优于AVL,也能保证时间复杂度为O(log2N)。
    • 红黑树插入时的不平衡,不超过两次旋转可以解决
    • 删除时的不平衡,不超过三次旋转可以解决。

介绍

红黑树是一种接近平衡的二叉树。

特性/要求

  1. 节点是红色或者黑色;
  2. 根是黑色;
  3. 叶子结点(外部节点,空节点)都是黑色,并且为空节点(概念上有空节点,实际无);
  4. 红色节点的子节点和父节点都是黑色(即,不存在两个连续的红色节点);
  5. 从任意节点到叶子结点的所有路径都包含相同数目的黑色节点

红黑树与二三四树

红黑树与二三四树等价

红黑树的黑色节点数 = 234树的节点数

在234树中的红黑树,黑色节点必为父节点,红色节点必为子节点;

(黑色中间,红色两边)

每一棵红黑树都有对应的唯一一棵二三四树;

但一个二三四树可能有多个红黑树与之对应。

高度

路径长度不会超过2log(n+1),即
$$
红黑树高度 \leq 2log(n+1)
$$

效率

红黑树的查找、插入和删除操作,时间复杂度都是O(logN)。

红黑树与AVL树比较

  1. AVL树时间复杂度优于红黑树;
  2. 红黑树整体性能略优于AVL树。

hole…

插入操作情况

插入结点的颜色

  • 若插入的是根节点,则为黑色

  • 其他节点为红色。

    • 如果插入红色节点,出现两个连续的红色节点,只需要旋转和变色进行调整。

为什么?

如果插入的颜色为黑色,则接下来的调整会非常麻烦;

如果插入的颜色为红色,则只有一种冲突的情况,只需要旋转和变色进行调整就可。

黑父

无需做任何操作;

image

红父

又分为两种情况:红叔、黑叔

红叔

image

若新节点的父节点和叔节点都是红色节点,将父节点和叔节点改为黑色,把祖节点改为红色,然后递归检查祖节点即可。

黑叔

黑叔分为4种情况处理;

  • 父节点是是祖节点的儿子,新节点是父节点的儿子
  • 父节点是是祖节点的儿子,新节点是父节点的儿子
  • 父节点是是祖节点的儿子,新节点是父节点的儿子
  • 父节点是是祖节点的儿子,新节点是父节点的儿子
父左新左

image

右旋,然后变色,叶子节点为黑色,其他向上交错;然后向上递归变色;

父右新右

image

左旋,然后变色,叶子节点为黑色,其他向上交错;然后向上递归变色;

父左新右

image

在父节点左旋,然后在祖节点右旋,最后变色,以叶子节点为黑色为基准,向上递归变色;

父右新左

image

在父节点右旋,然后在祖节点左旋,最后变色,以叶节点为黑色为基准,向上递归变色;

删除操作

分为两种情况:红色节点删除,黑色节点删除;

思想

B树中的删除操作,对于非叶子节点的删除,都要转换为其前驱/后继节点的删除

image

  • 这里要删除节点8,现将前驱节点要删除的节点值进行交换(这里是和6交换);
  • 然后删除前驱节点即可。

红色节点删除

可以直接删除,不做任何调整;

黑色节点删除

麻烦。必须进行调整才能满足红黑树的性质;即:从任意节点到叶子节点的所有路径都包含相同的黑色节点。

黑色节点的三种形式

  1. 有2个红色子节点的黑色节点;(即:234树的4节点
    • 不做考虑,对这个节点的删除会转换为对其子节点的删除。
  2. 有1个红色子节点的黑色节点;(即:234树的3节点
  3. 黑色叶子节点。(即:234树的2节点

有1个红色子节点的黑色节点

用唯一的红色子节点来替代被删除的节点,然后将替代的节点染为黑色

image

==步骤:替代,删除,将替代节点染黑==

删除没有子节点的黑色叶子节点

删除黑色叶子节点,会造成下溢的情况;

这里再分为三种情况:

  • 删除节点为根节点;
    • 此时整个红黑树只有这一个节点,可以直接删除。
  • 删除节点的兄弟节点为黑色;
  • 删除节点的兄弟节点为红色,这里要转变兄弟节点为黑色进行处理
删除节点的兄弟节点为黑色几种情况

分为以下几种情况:

  • 兄弟节点带有红色子节点(借用兄弟子节点修复)
    • 兄弟节点带有红色子节点
    • 兄弟节点带有红色子节点
    • 兄弟节点带有两个红色子节点
  • 兄弟节点没有红色子节点(父节点向下合并)
兄弟节点带有左红色子节点

image

兄弟节点带有右红色子节点

image

兄弟节点有两个红色子节点

image

兄弟节点没有红色子节点

这里分两种情况:

  • 父节点为红色节点
  • 父节点为黑色节点

父节点为红色节点

image

作为B树,没有任何变化;

作为红黑树,需要进行一次变色;

父节点为黑色节点

image

兄弟节点染为红色,父节点染为黑色;

如果父节点本就是黑色,就把父节点当做已被删除的节点处理,向上递归处理;

例子,==这里没能成功理解,后续回来==

image

兄弟节点为红色

这里要转变为黑色处理。

处理:父节点右旋,兄弟节点染为黑色,父节点染为红色,然后以兄弟节点为黑色进行修复

image

 评论