红黑树

0 阅读2分钟

基础

既然AVL已经很好了,为什么还要红黑树?

AVL树虽然查找效率更高(更平衡),但插入和删除时需要频繁旋转,维护成本较高;红黑树通过“弱平衡”减少旋转次数,使得插入和删除更高效,更适合工程实现。

结构平衡程度查询插入/删除
AVL严格平衡更快更慢(旋转多)
红黑树弱平衡稍慢更快(旋转少)

红黑树的核心思想:不追求高度差<=1,而是用“颜色规则”来控制树的平衡。

五大性质(颜色规则)

  1. 每个节点是红色或黑色
  2. 根节点是黑色
  3. 叶子节点(nullptr)是黑色
  4. 红节点不能相邻
  5. 黑高一致(从任意节点到所有叶子路径,黑色节点数量必须相同)

本质:保证“最长路径<=最短路径的2倍”

红黑树调整的核心问题:

首先,插入新节点必须是红色,因为如果插黑会破坏“黑高一致”的规则,插红只可能违反“红节点不能相邻”,所以红黑树调整的核心问题就是消除“红红冲突”。

三种情况

叔叔是红色

        G(黑)
       /     \
    P(红)   U(红)
    /
  N(红)--红红冲突

子和父都是红-》冲突-》父变黑-》父这一侧多了一个黑-》叔变黑-》 祖父这一侧多了层黑-》需要祖父变红来减少一个黑,但可能导致祖父和祖父的父亲红红冲突,所以继续向上调整(递归/循环)。

  • 父变黑
  • 叔变黑
  • 祖父变红
  • 向上继续处理
        G(红)--可能导致新的红红冲突
       /     \
    P(黑)   U(黑)
    /
  N(红)   

叔叔是黑色+直线(LL/RR)

旋转+变色

LL:

        G(黑)
       /     \
    P(红)    nullptr(黑)
    /
  N(红) --红红冲突

右旋:

        P(红)
       /     \
    N(红)   G(黑)

变色:

        P(黑)
       /     \
    N(红)   G(红)

RR:

           G(黑)
        /        \
nullptr(黑 )     P(红)
                   \
                   N(红) 

左旋:

        P(红)
       /     \
    G(黑)   N(红)

变色:

        P(黑)
       /     \
    G(红)   N(红)

故通过一次旋转(LL对应右旋,RR对应左旋)并调整颜色(父变黑,祖变红)即可。

叔叔是黑色+折线(LR/RL)

先旋转变成直线,然后就变成了情况二。

    G(黑)
   /
  P(红)
   \
    N(红)  

实现