红黑树

本文深入解析红黑树的定义、特点及其与2-3查找树的关系。探讨红黑树的插入与删除操作,包括不同情况下的调整策略。适用于对红黑树理论与实践感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义与特点

  • 红黑树的目的:由于2-3查找树是一种多叉树,实现起来较为麻烦,因此产生了红黑树。红黑树的基本思想是用标准的二叉查找树(全由2-结点构成)和一些额外的信息(替换3-结点)来表示2-3查找树。我们将树中的结点(或指向该结点的链接)分成两种类型:

    • 红链接:将两端的两个2-结点链接起来构成一个3-结点
    • 黑链接:2-3树中的普通链接

    红结点:将该红结点和其父结点(黑结点)链接起来构成一个3-结点 
    黑结点:2-3树中的2-结点

  • 红黑树的两种定义

    • 定义一(链接相关):通常用于和2-3查找树相联系 
      1. 红链接均为左链接 ——《算法》中的定义(便于旋转和转换成2-3查找树)
      2. 没有任何一个结点同时和两条红链接相连(即从每个叶子结点到根的所有路径上不能有两个连续的红色节点)
      3. 该树是完美黑色平衡树,即从任意结点向下出发的任意路径的黑链接数量相同
    • 定义二(结点相关):更通用的定义,之后的插入和删除都加上该定义(相当于2-3-4查找树——其中4结点表示黑结点的两个子结点为红色)

      1. 结点是红色或黑色的
      2. 更结点是黑色的
      3. 所有叶子结点(空结点)都是黑色的
      4. 从每个叶子结点(空结点)到根的所有路径上不能有两个连续的红色节点(即每个红色节点必须有两个黑色的子节点)
      5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点

  • 每棵2-3查找树都对应一棵红黑树,反之亦然

  • 选择并换色后,旋转子树的黑色结点数量通常不变

2-3查找树和红黑树插入方法比较

2-3查找树 红黑树(第一种定义的情况)
向2-结点插入新值 将一个红结点插入黑结点的左(右)链接
向一棵只含有一个3-结点的树(不含2-结点)插入新值 将一个红结点插入红结点(其父结点为黑根结点)的左(右)链接
向一个父结点为2-结点的3-结点插入新值 将一个红结点插入红结点(其父结点为黑结点,其爷爷结点为黑结点)的左(右)链接
向一个父结点为3-结点的3-结点插入新值 将一个红结点插入红结点(其父结点为黑结点,其爷爷结点为红结点,其太爷爷结点为黑结点)的左(右)链接

红黑树的插入操作

  • 基本概念:假设增加的结点总是初识为红色

    1. 性质1总是保持的
    2. 性质3只有在插入结点为根结点的情况下才会被破坏
    3. 性质4只在增加红色结点、重绘黑色结点为红色、或做旋转时受到威胁(此时常用的解决办法是重绘黑色或旋转)
    4. 性质5只在增加黑色结点、重绘红色结点为黑色、或做旋转时受到威胁(此时常用的解决办法是交换参与旋转的两个结点的颜色)
  • 一般情况下的三种情况(N是待插入结点,UN的叔叔结点):

    1. N的叔叔U是红色的
    2. N的叔叔U是黑色的,且N是右孩子
    3. N的叔叔U是黑色的,且N是左孩子

插入的五种情况

  1. 新节点N位于树的根上,没有父节点 
    • 问题:此时破坏了性质2
    • 解决方法:重绘该结点为黑色(维护了性质2)
  2. 新节点N的父节点P是黑色 
    • 问题:无(性质4和5都没有被破坏)
    • 解决方法:不做任何操作(直接插入)
  3. 新节点N的父节点P和叔父节点U二者都是红色

    • 问题:破坏了性质4
    • 解决方法

      1. P重绘为黑色(维护了性质4,但破坏了性质5)
      2. U重绘为黑色并重绘祖父节点G为红色(维护了性质5,但重绘后仍有可能破坏性质4,因此需要进行递归调节)

  4. 父节点P是红色而叔父节点U是黑色或缺少,并且新节点N是其父节点P的左子节点而父节点P又是其父节点G的左子节点(若为右子结点,则该情况的所有左右都对调)

    • 问题:破坏了性质4
    • 解决方法

      1. 针对祖父节点G的一次右旋转(破坏了性质5)
      2. 交换PG的颜色(维护了性质4和性质5)

  5. 父节点P是红色而叔父节点U是黑色或缺少,并且新节点N是其父节点P的右子节点而父节点P又是其父节点G的右子节点(若为左子结点,则该情况的所有左右都对调)

    • 问题:破坏了性质4
    • 解决方法

      1. 进行一次左旋转调换新节点和其父节点的角色,使其变成情况4
      2. 按情况4的方法进行调节

总结:执行任何操作后都检查有没有破坏其中任意一个性质

红黑树的删除操作

  • 二叉树删除操作的实现

    • 若被删除结点的度为0,则直接删除该结点即可
    • 若被删除结点的度为1,则直接删除该结点,并用该结点的子结点顶替
    • 若被删除结点的度为2,则将该结点的前驱或后继结点值替换该结点的值,再删除原前驱或后继结点
  • 因为度为2的结点的前驱结点和后继结点的度必定小于2,因此如果需要删除的节点有两个儿子,那么问题可以被转化成删除另一个只有一个儿子的节点的问题。所以我们只需要讨论删除只有一个儿子的节点(实际删除的结点)即可。

删除的八种情况

  1. 若被删除结点为红色

    • 问题:无 —— 由于红黑树的性质,该结点的父结点和子结点必定为黑色,此时性质3、4、5都不会被破坏
    • 解决方法简单的用它的黑色儿子来替换它即可
  2. 若被删除结点为黑色,而它的儿子结点是红色

    • 问题:如果只是去除这个黑色节点,用它的红色儿子顶替上来的话,不仅会破坏性质5,还有可能会破坏性质4
    • 解决方法重绘它的儿子为黑色并替换(等价于删除3-结点中的一个键)—— 这样即可维持性质5,也可维持性质4
  3. 若被删除结点为黑色,而它的儿子结点N也是黑色

    我们首先把要删除的节点替换为它的儿子。出于方便,称呼这个儿子为N(在新的位置上),称呼它的兄弟(替换后的新的父亲结点的另一个儿子)为S。在下面的示意图中,我们还是使用P称呼N的父亲,SL称呼S的左儿子,SR称呼S的右儿子。以下为删除后的调整阶段:

    1. N是新的根结点 
      • 问题:无 —— 因为这种情况下原先被删除的结点必定为根节点,所有路径都去除了一个黑色节点,而新根是黑色的,所以所有性质都没有被破坏
      • 解决方法不进行任何调整
    2. S是红色结点

      • 问题:破坏了性质5 —— 在这种情形下我们在N的父亲上做左旋转,把红色兄弟转换成N的祖父,我们接着对调N的父亲和祖父的颜色(使N有了一个黑色的兄弟和一个红色的父亲,但此时所有路径上黑色节点的数目没有改变)。接着按情形3.4、情形3.5或情形3.6来处理。
      • 解决方法N的父亲上做左旋转,把红色兄弟转换成N的祖父,我们接着对调N的父亲和祖父的颜色(使N有了一个黑色的兄弟和一个红色的父亲)。接着按情况3.4或3.5或3.6来处理

    3. N的父亲PN的兄弟S以及S的儿子SLSR都是黑色结点

      • 问题:破坏了性质5 —— 若我们简单的重绘S为红色,结果是通过P的所有路径的黑色结点数相同,但都比不通过P的路径少了一个黑色节点,所以仍然违反性质5。此时可以把该问题看成是在P和它的父结点之间原本还有一个黑结点,但被删除了(此时P为删除结点的儿子结点),因此可以从情形1(黑根结点)开始,在P上做重新平衡处理。
      • 解决方法::重绘S为红色,并且从情形1(黑根结点)开始,在P上做重新平衡处理。

    4. N的兄弟结点S以及S的儿子结点(SLSR)都是黑色,但N的父亲结点P是红色

      • 问题:破坏了性质5 —— 交换N的兄弟S和父亲P的颜色(这不影响不通过N的路径的黑色节点的数目,但是它在通过N的路径上对黑色节点数目增加了一,添补了在这些路径上删除的黑色节点)
      • 解决方法交换N的兄弟S和父亲P的颜色

    5. N的兄弟结点S为红色,S的左儿子结点SL为红色,右儿子结点SR为黑色

      • 问题:性质5依旧被破坏 —— 在S上做右旋转(使S的左儿子SL成为S的父亲和N的新兄弟),接着交换S和它的新父亲的颜色(此时该旋转子树中的所有路径仍有同样数目的黑色节点,此举的目的是使N有一个黑色兄弟,且该兄弟结点的右儿子是红色的,但N和它的父亲P都不受这个变换的影响),最后进入了情形3.6。
      • 解决方法S上做右旋转,接着交换S和它的新父亲的颜色,最后进入了情形3.6

    6. S是黑色,S的右儿子SR是红色,而N是它父亲P的左儿子

      • 问题:破坏了性质5 —— 在N的父亲P上做左旋转,这样S成为P的父亲。我们接着交换PS的颜色,并使S的右儿子(SR)为黑色(此时N现在增加了一个黑色父亲,所以通过N的所有路径都增加了一个黑色节点,而不通过N的所有路径上的黑色节点数目都没有改变)
      • 解决方法N的父亲P上做左旋转,接着交换PS的颜色,并使S的右儿子(SR)为黑色

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值