什么是红黑树(内存最优的二叉树)

一.红黑树定义

    红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组

    它是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees)。后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的"红黑树"。

    红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能

    它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的是树中元素的数目。

二.红黑树是一种含有红黑结点并能自平衡的二叉查找树。它必须满足下面性质:

  • 性质1:每个节点要么是黑色,要么是红色。
  • 性质2:根节点是黑色。
  • 性质3:每个叶子节点(NULL)是黑色。(同234树)
  • 性质4:每个红色结点的两个子结点一定都是黑色。
  • 性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。
  • 性质5.1:如果一个结点存在黑子结点,那么该结点肯定有两个子结点。(由5推出)
  •     这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。
  •     要知道为什么这些特性确保了这个结果,注意到性质4导致了路径不能有两个毗连的红色节点就足够了。最短的可能路径都是黑色节点,最长的可能路径有交替的红色和黑色节点。因为根据性质5所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。

        在很多树数据结构的表示中,一个节点有可能只有一个子节点,而关联数组不包含数据。用这种范例表示红黑树是可能的,但是这会改变一些属性并使算法复杂。为此,本文中我们使用 "nil 叶子" 或"空(null)叶子",如上图所示,它不包含数据而只充当树在此结束的指示。这些节点在绘图中经常被省略,导致了这些树好象同上述原则相矛盾,而实际上不是这样。与此有关的结论是所有节点都有两个子节点,尽管其中的一个或两个可能是空叶子。

三.构建原则

因为红黑树是一颗二叉平衡树,并且查找不会破坏树的平衡,所以查找跟二叉平衡树的查找无异:

  1. 从根结点开始查找,把根结点设置为当前结点;
  2. 若当前结点为空,返回null;
  3. 若当前结点不为空,用当前结点的key跟查找key作比较;
  4. 若当前结点key等于查找key,那么该key就是查找目标,返回当前结点;
  5. 若当前结点key大于查找key,把当前结点的左子结点设置为当前结点,重复步骤2;
  6. 若当前结点key小于查找key,把当前结点的右子结点设置为当前结点,重复步骤2;

插入操作包括两部分工作:一查找插入的位置;二插入后自平衡。查找插入的父结点很简单,跟查找操作区别不大:

  1. 从根结点开始查找;
  2. 若根结点为空,那么插入结点作为根结点,结束。
  3. 若根结点不为空,那么把根结点作为当前结点;
  4. 若当前结点为null,返回当前结点的父结点,结束。
  5. 若当前结点key等于查找key,那么该key所在结点就是插入结点,更新结点的值,结束。
  6. 若当前结点key大于查找key,把当前结点的左子结点设置为当前结点,重复步骤4;
  7. 若当前结点key小于查找key,把当前结点的右子结点设置为当前结点,重复步骤4;

红黑树的删除操作也包括两部分工作:一查找目标结点;而删除后自平衡。查找目标结点显然可以复用查找操作,当不存在目标结点时,忽略本次操作;当存在目标结点时,删除后就得做自平衡处理了。删除了结点后我们还需要找结点来替代删除结点的位置,不然子树跟父辈结点断开了,除非删除结点刚好没子结点,那么就不需要替代。

二叉树删除结点找替代结点有3种情情景:

  • 情景1:若删除结点无子结点,直接删除
  • 情景2:若删除结点只有一个子结点,用子结点替换删除结点
  • 情景3:若删除结点有两个子结点,用后继结点(大于删除结点的最小结点)替换删除结点

补充说明下,情景3的后继结点是大于删除结点的最小结点,也是删除结点的右子树种最左结点。那么可以拿前继结点(删除结点的左子树最右结点)替代吗?

可以的。但习惯上大多都是拿后继结点来替代,后文的讲解也是用后继结点来替代。另外告诉大家一种找前继和后继结点的直观的方法(不知为何没人提过,大家都知道?):把二叉树所有结点投射在X轴上,所有结点都是从左到右排好序的,所有目标结点的前后结点就是对应前继和后继结点




具体内容可见链接:https://www.jianshu.com/p/e136ec79235c

 

 

<think>好的,用户想了解二叉树红黑树的区别,以及红黑树的定义和创建方法。首先,我需要回忆一下二叉树红黑树的基本概念。根据引用[1],二叉树是一种数据结构,每个节点最多有两个子节点。而红黑树属于平衡二叉树的一种,引用[2]提到平衡二叉树要求左右子树高度差不超过1,但红黑树可能放宽了这个条件,通过颜色标记和旋转来保持平衡。 接下来,用户问两者的区别。我需要从平衡性、操作复杂度、应用场景等方面比较。引用[4]指出,AVL树是严格的平衡,而红黑树通过特性实现近似平衡,可能减少旋转次数,插入删除更快。同时,引用[3]提到红黑树的操作时间复杂度是O(logn),和AVL一样,但实际可能常数更小。 然后是红黑树的定义。根据引用[3]和[4],红黑树有五个特性:节点颜色、根和叶子是黑色、红色节点的子节点必须黑色、路径黑节点数相同。这些需要详细列出。 关于创建方法,用户可能需要插入节点的步骤,包括颜色调整和旋转操作。引用[3]提到变色、左旋、右旋是维持平衡的手段。需要解释插入过程如何处理颜色冲突,必要时进行旋转。 还要注意用户可能不太了解技术细节,需要用易懂的语言解释,避免过于术语化。同时,根据系统指令,数学公式要用$...$,例如节点颜色属性用$颜色∈\{红,黑\}$。 检查引用是否正确,例如引用[4]讨论红黑树的应用和特性,引用[2]说明平衡二叉树的要求。需要确保每个引用标注准确,没有混淆。 最后,生成相关问题,可能涉及红黑树的应用、与AVL树的对比、时间复杂度等,确保问题覆盖用户可能感兴趣的扩展内容。</think>### 二叉树红黑树的区别 #### 1. 核心区别 - **平衡性要求** - **普通二叉树**:无平衡性约束,极端情况下可能退化为链表,时间复杂度退化到$O(n)$[^2][^3]。 - **红黑树**:通过以下规则实现**近似平衡**,保证操作复杂度稳定在$O(\log n)$[^3][^4]: 1. 每个节点具有颜色属性(红或黑); 2. 根节点和叶子节点(NIL空节点)为黑色; 3. 红色节点的子节点必须为黑色; 4. 从根到任意叶子节点的路径包含相同数量的黑色节点。 - **操作效率** - 红黑树通过放宽平衡条件(允许局部不平衡),减少插入/删除时的旋转次数,综合效率更高[^4]。 - AVL树严格平衡(高度差≤1),查询更快但维护成本更高;红黑树更适合频繁修改的场景[^3][^4]。 #### 2. 红黑树的定义 红黑树是满足以下特性的二叉查找树: 1. **颜色属性**:每个节点颜色为$红$或$黑$; 2. **根与叶子**:根节点和所有NIL叶子节点为$黑$; 3. **红色限制**:红色节点的子节点必须为$黑$; 4. **黑高一致**:任意路径的黑节点数相等[^3][^4]。 --- ### 红黑树的创建方法 #### 1. 插入操作步骤 1. **按二叉查找树规则插入**:新节点初始为红色; 2. **颜色修正**:若父节点为红色,触发修正逻辑: - **Case 1**:叔节点为红色 - 将父节点和叔节点变黑,祖父节点变红; - 递归处理祖父节点。 - **Case 2**:叔节点为黑且新节点与父节点方向不一致 - 通过旋转(左旋/右旋)调整为同方向。 - **Case 3**:叔节点为黑且方向一致 - 父节点变黑,祖父节点变红; - 对祖父节点旋转[^4]。 #### 2. 示例代码(Java风格伪代码) ```java class Node { int val; Node parent, left, right; Color color; // 红或黑 } void insertFixup(Node z) { while (z.parent.color == RED) { if (z.parent == z.parent.parent.left) { Node uncle = z.parent.parent.right; if (uncle.color == RED) { // Case 1 z.parent.color = BLACK; uncle.color = BLACK; z.parent.parent.color = RED; z = z.parent.parent; } else { if (z == z.parent.right) { // Case 2 z = z.parent; leftRotate(z); } // Case 3 z.parent.color = BLACK; z.parent.parent.color = RED; rightRotate(z.parent.parent); } } else { // 对称处理右子树情况 // ... } } root.color = BLACK; } ``` --- ### 引用说明 - 红黑树通过变色和旋转维持平衡,时间复杂度稳定在$O(\log n)$[^3]。 - 与AVL树相比,红黑树牺牲部分查询效率换取更高效的插入/删除操作,适合内存数据库、Java集合等场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值