当前位置: 首页 > article >正文

8.BST的缺陷解决方案:平衡树*****

目录

1. AVL树

1.1 性质

1.2 具体实现细节

大概如何实现的逻辑:

怎样平衡:

1.3 性能

2. 红黑树

2.1 性质

2.2 具体实现细节

怎样平衡:

2.3 性能

3. AVL 与 RBT 的区别


1. AVL树

1.1 性质

AVL树也叫“高度平衡二叉搜索树”:

  • 它的左右子树都是AVL树
  • 左右子树高度之差(平衡因子)的绝对值不超过1

1.2 具体实现细节

2. AVL树-CSDN博客

大概如何实现的逻辑:

AVL树是一种自平衡二叉搜索树,通过维护每个节点的平衡因子(左右子树高度差不超过1)来确保树的平衡。其核心实现包括

  • 每个节点包含键值、左右子节点指针和高度信息。

  • 平衡因子 = 左子树高度 - 右子树高度,必须为 -1、0 或 1。

    • 按二叉搜索树规则插入节点。

    • 更新节点高度。

    • 检查平衡因子,若失衡则通过旋转恢复平衡。

怎样平衡:

根据插入结点后,父节点的平衡因子的大小,以及新插入的节点的位置,进行平衡操作。

  • 父节点的平衡因子 = 0,平衡,不用向上更新
  • -1 / 1,有点小病,问题不大,需要向上更新
  • -2 / 2,失衡,需要根据插入结点的位置选择旋转方式
    • 右右-左单旋
    • 右左-右左双旋
    • 左左-右单旋
    • 左右-左右双旋

1.3 性能

        AVL树是一棵绝对平衡的二叉搜索树,这可以保证查询时高效的时间复杂度 O(logN) 。但是如果要对AVL树做一些结构修改的操作,性能非常低下,比如:插入时因为要维护绝对平衡,旋转的次数比较多,更差的是在删除时,有可能一直要让旋转持续到根的位置。

        因此:如果需要一种查询高效且有序的数据结构,而且数据的个数为静态的(不增不减),可以考虑AVL树,但一个结构经常修改的话就不太合适。

2. 红黑树

2.1 性质

        红黑树也是一种BST,但在每个结点上增加一个存储位标识结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因此是接近平衡的。

  • 每个结点是 红色 或 黑色
  • 根结点是 黑色
  • 叶子节点(空节点)都是黑色,这里的叶子节点指的是最底层的空节点(外部节点),那些null节点才是叶子节点
  • 红色节点的孩子都是黑色
    • 红色节点的父亲都是黑色
    • 从根到NULL结点的所有路径上不能有 2 个连续的红色节点
  • 从任一节点到叶子节点的所有路径都包含相同数目的黑色节点

2.2 具体实现细节

3. 红黑树-CSDN博客

怎样平衡:

插入的框架和AVL树类似,不同处出现在旋转的判断:

        由于新插入的节点默认为红色,若它的父亲为黑色,直接插入就行;如果它的父亲为红色此时父与子都是红色,违反了“不能有两个连续红色节点”的规则,需要进行处理:

        由于我们需要知道新节点的uncle的信息,所以要分左右:

  • 如果 p(parent) 在 g(grandfather) 的 左,那么 u(uncle) 就在 g 的右
  • 如果 p(parent) 在 g(grandfather) 的 右,那么 u(uncle) 就在 g 的左

上面两种情况都有各自的处理方式:

第一种:p 在 g 的左,u 在 g 的右:

  • 如果u存在且为红色,此时 p 和 u 和 cur 为红色,此时最长路径的长度没有超过最短二倍:
    • 把 p 和 u 变黑,g 变红,此时继续向上更新,c = g,p = c→_parent:
      • 若 g 没有父亲,就是根,g变回黑即可
      • g 有父亲,且父亲为黑色,结束
      • g 有父亲,且父亲为红色,此时又出现了两个连续节点为红的情况,判断p 在 g的左还是右,就变成了上面分左右的两种情况
  • 如果 u 不存在 或 u 为黑,此时 cur 为红,p 是红,此时最长路径的长度超过最短的二倍,单纯的变色无法解决问题,需要根据新增节点在p的左/右分情况进行旋转+变色
    • 如果 c 在 p 的左,此时由于 p 在 g 左,g、p、c 构成 左左-右单旋
      • RotateR(grandfather),p 由红变黑,g 由黑变红
    • 如果 c 在 p 的右,此时由于 p 在 g 左,三个节点构成 左右-左右双旋
      • RotateL(parent)-折线变直线,RotateR(grandfather)-直线变三角,cur 由红变黑,g由黑变红

第二种:p 在 g 的右,u 在 g 的左:

  • 如果u存在且为红色,此时 p 和 u 和 c是红色此时最长路径的长度没有超过最短二倍
    • 把 p 和 u 变黑,g 变红,此时继续向上更新,c = g,p = c→_parent:
      • 若 g 没有父亲,就是根,g变回黑即可
      • g 有父亲,且父亲为黑色,结束
      • g 有父亲,且父亲为红色,此时又出现了两个连续节点为红的情况,判断p 在 g的左还是右,就变成了上面分左右的两种情况
  • 如果 u 不存在 或 u 为黑,此时 cur 为红,p 是红,此时最长路径的长度超过最短的二倍,单纯的变色无法解决问题,需要根据新增节点在p的左/右分情况进行旋转+变色
    • 如果 c 在 p 的右,此时由于 p 在 g 右,g、p、c 构成 右右-左单旋
      • RotateL(grandfather),p 由红变黑,g 由黑变红
    • 如果 c 在 p 的左,此时由于 p 在 g 右,三个节点构成 右左-右左双旋
      • RotateR(parent)-折线变直线,RotateL(grandfather)-直线变三角,cur 由红变黑,g由黑变红

我们可以总结出规律红黑树插入关键看uncle:

        如果 uncle 存在且为红,不管uncle在gradfather的左还是右,这种只需要变色的情况,两种情况变色的过程是相同的

        如果 uncle 不存在 或 存在且为黑,此时两种情况也只是因为 parent 相对于 grandfather 的左或右(因为 cur 在 parent 的左或右这两种情况都会出现,所以不影响),在旋转方式上有所不同,但他们的节点变色过程是一样的。

2.3 性能

        红黑树的核心操作(查找、插入、删除)的时间复杂度均为 O(log n)。红黑树不追求绝对平衡,只需保证最长路径不超过最短路径的两倍,相对而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树的实现比较简单,所以实际运用中红黑树更多。

3. AVL 与 RBT 的区别

特性AVL 树红黑树(RB-Tree)
平衡标准严格平衡(左右子树高度差 ≤1)弱平衡(最长路径 ≤2倍最短路径)
查找效率更高(严格平衡,查找稳定 O(log⁡n))稍低(但仍是O(logn))
插入/删除效率较低(可能需要更多旋转调整)较高(调整次数更少)
旋转操作频率频繁(每次插入/删除都可能调整)较少(颜色调整优先于旋转)
适用场景适合读多写少(如数据库索引)适合频繁插入/删除(如STL map)
实现复杂度较高(需维护严格的平衡因子)较低(只需满足5条红黑性质)
存储开销每个节点需存储平衡因子(int)每个节点只需1 bit存储颜色
调整策略主要通过旋转恢复平衡旋转 + 重新着色

http://www.kler.cn/a/599432.html

相关文章:

  • 什么是索引?为什么要使用B树作为索引数据结构?
  • 股指期权最后交易日是哪一天?
  • Flask(一)概述与快速入门
  • 蓝桥杯备考:学会使用方向向量
  • Pyserial库使用
  • HRP方法全文总结与模型流程解析
  • Flutter 输入组件 Radio 详解
  • Blender4.4正式发布:核心更新与渲染101云渲染平台应用指南
  • TCP/IP协议的三次握手和四次挥手
  • 《大语言模型赋能证券业开发安全:海云安技术方案在上交所专刊发表》
  • spring boot项目中Lombok注解失效问题
  • 初阶数据结构(C语言实现)——6.2选择排序详解(思路图解+代码实现)
  • 机器学习之回归
  • CES Asia 2025:科技企业出海的领航灯塔
  • Go常见问题与回答(上)
  • 大数据平台各组件功能与协同作用全解析
  • 【AndroidRTC-11】如何理解webrtc的Source、TrackSink
  • 100天精通Python(爬虫篇)——第122天:基于selenium接管已启动的浏览器(反反爬策略)
  • python如何创建虚拟环境
  • 科技赋能,高端气膜料仓重塑储存新标准—轻空间