数据结构—红黑树

红黑树是为了解决AVL树删除节点后频繁大规模旋转的问题,保证搜索、插入和删除操作的时间复杂度为O(logn)。它有五条约束,包括节点颜色、黑高度平衡等。插入操作只在特定情况下需旋转,删除操作最多涉及常数次旋转。红黑树通过限制旋转次数,降低了拓扑结构调整的频率。

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

1. 简介

AVL 树在删除节点之后可能需要多达 O ( log ⁡ n ) O(\log n) O(logn) 次的旋转才能够使整棵树恢复平衡,但也因此导致了全树拓扑结构频繁地发生大幅度的变化。

红黑树主要是针对上述不足所做的改进,它也是一棵平衡二叉搜索树,且可以保证每次插入、删除操作之后的重平衡过程中,全树拓扑结构的更新仅涉及常数个节点。

红黑树的搜索、插入和删除操作的时间复杂度也为 O ( log ⁡ n ) O(\log n) O(logn)

2. 约束

红黑树具有如下约束:

(1)每个节点要么为红色,要么为黑色;
(2)树根始终为黑色;
(3)若一个节点为红色,则其左右孩子必为黑色;
(4)从任一节点通往其任一后代叶节点的路径中,黑色节点的总数(称为黑高度)必定相等。

设节点总数为 n n n,则红黑树的高度为 O ( log ⁡ n ) O(\log n) O(logn)。但相比于 AVL 树而言,红黑树无法做到 AVL 树那样严格的适度平衡。

3. 插入

(1)首先和普通的二叉搜索树一样插入新节点 x x x,并将其染为红色;
(2)如果 x x x 为树根,则将其染为黑色,然后成功返回;否则,
(3)如果 x x x 的父节点为黑色,则成功返回;否则即出现“双红”现象(节点 x x x 及其父节点均为红色),
(4)设 x x x 的父节点为 p p p(红色), p p p 的父节点为 g g g(黑色), p p p 的兄弟节点为 u u u

根据 u u u 的颜色的不同(定义空节点的颜色为黑色)可分为两种情况进行处理。

RR-1:节点 u u u 为黑色的情况

根据 g , p , x g,p,x g,p,x 的方向又可以分为四种情况,下图中的(a)和(b)即为对应的两种情况,另外两种与(a)、(b)对称。

在这里插入图片描述

情况(a):以 g g g 为轴进行一次 zig 旋转,然后将 p p p 染为黑色,将 g g g 染为红色(因为 u u u 为黑色,所以没事)。(此时, a = x , b = p , c = g a=x,b=p,c=g a=x,b=p,c=g

情况(b):先以 p p p 为轴进行一次 zag 旋转,然后以 g g g 为轴进行一次 zig 旋转,然后将 x x x 染为黑色,将 g g g 染为红色(因为 u u u 为黑色,所以没事)。(此时, a = p , b = x , c = g a=p,b=x,c=g a=p,b=x,c=g

RR-2:节点 u u u 为红色的情况

根据 g , p , x g,p,x g,p,x 的方向又可以分为四种情况,下图中的(a)和(b)即为对应的两种情况,另外两种与(a)、(b)对称。
在这里插入图片描述此时只需将 p , u p,u p,u 染为黑色,将 g g g 染为红色即可。但此时又可能会导致 g g g 及其父节点发生“双红”现象,所以此时需要递归向上判断、处理双红现象。

由上可见,只有在 RR-1 情况中才需要进行旋转操作(改变树的拓扑结构),而且旋转过后,重平衡过程即宣告完毕。所以,红黑树的插入操作仅涉及到常数次的拓扑调整。

4. 删除

x x x 的接替者为 r r r x x x 的父节点为 p p p

(1)首先根据普通的二叉搜索树的删除过程删除节点 x x x,并使用 r r r 替换 x x x
(2)若 x x x 为红色,则成功返回;否则,
(3)若 x x x 为黑色,且 r r r 为红色,则只需将 r r r 染为黑色即可成功返回;否则,
(4)若 x , r x,r x,r 均为黑色,则出现“双黑”现象;此时,将 x x x 的兄弟节点记为 s s s(非空,否则违背约束(4));

根据 s , p s,p s,p 颜色的不同,具体可分为四种情况进行处理。

BB-1: s s s 为黑色,且至少有一个红色子节点, p p p 的颜色不定

s s s 的红色子节点记为 t t t,则一种可能情况如下图中的(a)所示:

在这里插入图片描述
其他情况类似或与此对称。

此时,对 t , s , p t,s,p t,s,p 进行单旋或双旋(也可以进行“3+4”重构),然后将 t , p t,p t,p 染为黑色,令 s s s 继承 p p p 原来的颜色即可。

BB-2: s s s 为黑色,且无红色子节点, p p p 为红色

一种可能情况如下图中的(a)所示,另一种情况与此对称:

在这里插入图片描述

此时只需将 s s s 染为红色,将 p p p 染为黑色即可。

BB-3: s s s 为黑色,且无红色子节点, p p p 为黑色

一种可能情况如下图中的(a)所示,另一种情况与此对称:
在这里插入图片描述
此时可将 s s s 染为红色,保证局部子树满足约束,但就全局来看,约束(4)不一定成立,因为子树 p p p 的黑高度减少了一。

为此,可以等效地看做又发生了一次删除操作:节点 p p p (等价于原来的 r r r)的一个黑色父节点(等价于原来的 x x x)刚被删除,因此可以递归地解决“双黑”现象。

BB-4: s s s 为红色

此时 p p p 必为黑色, s s s 的子节点必为黑色。

一种可能情况如下图中的(a)所示,另一种情况与此对称:

在这里插入图片描述

此时可以 p p p 为轴进行一次 zig 旋转,然后将 p p p 染为红色,将 s s s 染为黑色。

上述操作并没有直接解决“双黑”现象,相反,它只是将其转换为 BB-1 或 BB-2 情况(此处的 s ′ s' s 对应原来的 s s s)。

综上所述,红黑树的删除操作最多也只需常数次的旋转(调整全树拓扑结构)。

### 红黑树数据结构介绍 红黑树是一种自平衡二叉查找树,在实际应用中非常常见,尤其在标准模板库(STL)中的`map`和`set`容器底层实现上得到了广泛应用[^1]。 #### 定义与特性 红黑树具有以下性质: - 每个节点要么是红色,要么是黑色。 - 根节点总是黑色。 - 所有叶子节点都是黑色的NIL节点(表示不存在的实际对象)。 - 如果一个内部节点是红色,则其两个子节点都必须是黑色。(即不允许存在相邻的红色节点) - 对于任意节点而言,从该节点到其可达叶子节点的所有路径均包含相同数量的黑色节点。 这些属性共同作用使得红黑树能够在最坏情况下保持O(log n)的时间复杂度完成插入、删除以及查询操作。 #### 实现细节 关于红黑树的具体实现较为复杂,尤其是旋转调整部分。这里给出一段简化版的Python代码用于展示基本框架: ```python class Node: def __init__(self, item=None): self.item = item self.parent = None self.left = None self.right = None self.color = 'red' # 新加入结点默认为红色 class RedBlackTree: def __init__(self): self.TNULL = Node() self.root = self.TNULL def insert(self, key): ... def delete_node(self, node): ... def left_rotate(self, x): ... def right_rotate(self, y): ... ``` 上述代码仅展示了类定义的一部分;完整的逻辑还包括左旋/右旋方法、插入修正函数等更多内容[^4]。 #### 应用场景 由于良好的时间复杂性和相对简单的维护成本,红黑树被广泛应用于各种编程语言的标准库之中。例如Java集合框架里的`TreeMap`就采用了类似的机制来存储键值对[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值