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

红黑树,B树,二叉树之间的不同

二叉树

二叉树是一种树状结构,每个节点最多只有两个子节点:左子节点和右子节点。

结构

        A/ \B   C/ \   \D   E   F

这里:

  • A是根节点
  • B和C是A的子节点
  • D和E是B的子节点
  • F是C的子节点

基本术语

  • 节点(Node):树的每个元素,比如A、B、C
  • 根节点(Root):树的最顶端节点,比如以上示例的A
  • 叶子节点(Leaf):没有子节点的节点(D、E、F)
  • 子节点(Child):某节点的直接下级节点(B是A的子节点,D是B的子节点)
  • 父节点(Parent):某节点的上级节点(D的父节点是B,B的父节点是A)
  • 深度(Depth):节点到根的距离(层数)
  • 高度(Height):节点到叶子节点的最长路径
深度(Depth)高度(Height)
定义节点到的距离(层数)节点到叶子的最长路径(层数)
例子根深度为0,叶子深度为最大叶子高度为0,树根高度最大,反映从节点到叶子路径

深度和高度不同,不要搞错了。

类型

类型描述举例
普通二叉树任意节点最多两个子节点上面示意的树
满二叉树所有叶子节点都在同一层,且每个非叶子节点有两个子节点每层的节点数都满
完全二叉树除最后一层外,每层节点都满,最后一层节点尽可能集中在左侧完全二叉堆
平衡二叉树任意节点左右子树高度差不超过1AVL树、红黑树

遍历方式

  • 前序遍历(Pre-order): 根 -> 左子树 -> 右子树
  • 中序遍历(In-order): 左子树 -> 根 -> 右子树
  • 后序遍历(Post-order): 左子树 -> 右子树 -> 根
  • 层序遍历(Level-order): 按层从上到下、从左到右

示例:
假设树如下:

        A/ \B   C/ \   \D   E   F
  • 前序:A -> B -> D -> E -> C -> F
  • 中序:D -> B -> E -> A -> C -> F
  • 后序:D -> E -> B -> F -> C -> A
  • 层序:A, B, C, D, E, F

性质

  • 节点数关系:
    在一棵二叉树中,节点总数为:

                          ∇=叶子节点数+非叶子节点数
    
  • 深度与高度:

    • 树的深度(层数)越多,树越高
    • 平衡的二叉树操作通常为了减少树的高度,以优化性能

二叉搜索树

对于树中的每个节点:

  • 左子树上所有节点的值都小于这个节点的值
  • 右子树上所有节点的值都大于这个节点的值
    这样,整棵树就按照“二叉搜索树的性质”排序了。

实例

假设插入数字:10, 5, 15, 3, 7

结构大致是:

        10/   \5     15/ \3   7
  • 每个节点左边都比它小,右边都比它大
  • 可以快速实现搜索、插入、删除

作用

  • 快速查找:通过中序遍历,得到一个有序序列
  • 基础结构:很多复杂的树(如AVL、红黑树)都是在BST基础上改进的
  • 应用广泛:数据库索引、字典等

平衡二叉树

平衡二叉树是一类特殊的二叉搜索树,其任何节点的左右子树的高度差(平衡因子)都不超过1。这样保证树的高度始终保持在 logn 的级别。

使用平衡二叉树的原因

  • 普通BST在极端情况下可能退化成链表:

    • 比如按顺序插入有序数据,会形成一条长链,查找变为线性时间 O(n)。
  • 平衡树维持树的高度最小化,保证查找、插入、删除操作高效。

常见的平衡二叉树

  • AVL树(Adelson-Velsky and Landis Tree)

    • 平衡因子(Balance factor):每个节点左子树高度减右子树高度,要求为-1、0、1。
    • 每次插入或删除后,可能需要“旋转”操作来修复平衡。
  • 红黑树

    • 性质:每个节点是红或黑,满足特定规则,使树始终大致平衡。
    • 特点:插入、删除后通过“变色”和“旋转”保持平衡,常用于Java的TreeMap、C++的map。

实例

以AVL树为例:如何保持平衡

  • 插入/删除节点后:

    • 从插入位置向上回溯,检测每个节点的平衡因子
    • 如果某个节点的平衡因子超出范围(>1 或 <-1),就需要“旋转”调整
  • 旋转类型:

  • 左旋(Single Left Rotation)

  • 右旋(Single Right Rotation)

  • 左右旋(Left-Right Rotation)

  • 右左旋(Right-Left Rotation)

这些旋转操作帮助重新平衡树,保持每个节点的平衡因子在允许范围内。

旋转

单旋转
  • LL旋转(左左不平衡 -> 右旋)

场景:
插入新节点后,左子树的左子节点变得过高,导致树左侧“倾斜”。

    不平衡前                     旋转后A                            B/                            / \B        —— 右旋 ——          C   A/                                C                                
  • 将A进行右旋转 将节点B作为新的根节点,A成为B的右子节点,C(原B的左子节点)作为A的左子节点。
  • RR旋转(右右不平衡 -> 左旋)

场景:
插入新节点后,右子树的右子节点变得过高。

  不平衡前                     旋转后A                             B\                         /   \B        —— 右旋 ——      A     C\                           \C                           D
  • 将A左旋转 成为左节点
双旋转
  • LR旋转(左-右不平衡)

场景:
左子树的右子树高,需先左旋左子树,再右旋根节点。

不平衡前                         旋转后A                              /                             B        —— 先左旋 B 在右旋A ——   B   \                            /  \ C                          C    A

总结

特点说明
每个节点的平衡因子(左右子树高度差) ≤ 1 \leq 1 1(即-1, 0, 1)
保持树的高度在 log ⁡ n \log n logn 级别确保操作时间为 $ O(\log n) $
通过旋转调整平衡在插入、删除操作后自动修复

旋转子树时其他不变,当子树旋转结束后,谁是子树根节点,全树的根节点就连接谁。

红黑树

红黑树是一类自平衡的二叉搜索树,它通过“颜色标记”以及一系列规则,确保树的高度大致平衡,从而在插入、删除和查找操作中实现 O(logn) 的时间复杂度。

节点属性

每个节点有:

  • 一个值(数据)
  • 一个颜色(红或黑)
    • 在红黑树的定义中,黑色节点的数量(黑高)决定了路径的长度,而红色节点只是“装饰”
    • 红节点不增加黑色节点的数量,只是“点缀”,用于调节树结构。
    • 黑节点:像“楼层数”,决定了路径的基本高度。
    • 红节点:像“楼层之间的装饰”,不会加高,但帮助控制设计。
  • 指向左右子节点的指针
  • 指向父节点的指针(有的实现会有)

结构

        (8B)/     \(4R)     (12R)/  \      /   \(2B) (6B) (10B) (14B)
  • R代表红色,B代表黑色

关键属性

  • 节点是红色或黑色
  • 根节点是黑色
    • 保持树的“起点”黑色,有助于维护路径上黑色节点的平衡。
    • 这样可以避免频繁出现连续的红色起点,也简化性质的维护。
  • 所有叶子(NIL节点,即空子节点)都是黑色
    • 方便统一处理空子节点,简化算法设计。
    • 通过将叶子定义为黑色,确保路径中的黑色节点计数一致。
  • 红色节点的子节点必须是黑色(不能连续两个红节点)
    • 连续的红色节点会导致路径中的黑色节点数变少,从而使树高度偏高,平衡性差
  • 从任何节点到叶子节点的所有路径都包含相同数目的黑色节点(黑色平衡)

作用与优势

  • 保持树的平衡:通过颜色规则避免树变得太高(退化为链表)。
  • 保证操作效率:插入、删除、查找都在 O(logn) 范围内。

插入操作

插入新节点类似BST:

  • 新节点总是插入为红色(为了不是破坏黑色平衡)
  • 然后修复颜色和旋转,保持红黑性质

插入修复(修复红色连续性)

可能出现:

  • 红节点的父节点也是红色(违反性质 4)

修复方法:

  • 情况1:叔叔节点为红色
       A/  \B    C/ \D   E
  • D的父节点是 B。

  • B的兄弟节点(父节点的兄弟)就是 C。

    • 将父节点和叔叔节点变为黑色
    • 将祖父节点变为红色
    • 继续向上修正
  • 情况2:叔叔节点为黑色或不存在(空节点)

    • 进行左旋或右旋调整,以恢复性质,往往以“旋转+颜色调整”完成
状况处理方法
父节点是红色,叔叔节点是红色变色 + 重新向上修复
父节点是红色,叔叔节点是黑色(或不存在)旋转 + 变色(形成左右旋转的调整)

例:

插入节点7

  • 作为红色节点插入
  • 如果父节点是黑色,无需调整
  • 如果父节点是红色(出现连续红色),进行旋转和颜色调整

删除操作

  • 类似BST,但需要调整来恢复红黑性质
  • 可能涉及“向下传递”的颜色和旋转调整

核心思想

  • 红黑树通过限制“连续红节点“和”黑色路径长度一致“,保证树的高度在”对数级“
  • 调整主要依靠颜色变换和旋转

总结

特性描述
节点颜色每个节点是红或黑
根节点必须是黑色
叶子节点(NIL)全部是黑色,作为叶节点,用来简化算法
红色节点的子节点必须是黑色(不能连续两个红色节点)
所有路径的黑色节点数相同从根到任意叶子路径,黑色节点数一致(黑高平衡)

如果出现连续红节点会出现的问题:

  • 形成连续的红色链(如:连续三个红色节点),
  • 破坏黑色节点平衡的性质(因为黑色节点数变少了),
  • 使得树的高度可能增长,变得不平衡。

红黑树的设计宗旨是限制红色链的长度:

  • 规则“红色节点的子节点必须是黑色”,实际上限制了连续红色的长度最多为1。
  • 这样,路径上的红色节点最多只有一层,避免了“红色链”无限长,从而保证树的平衡。

B树

  • B树是一棵阶数为 m 的多路平衡搜索树。
  • 每个节点最多有 m 个子节点(即 m-1 个关键字)。

基本性质

  • 每个内部节点(非叶子节点):
    • 含有 k (m/2 - 1 ≤ k ≤ m-1) 个关键字
    • 有 k+1 个子节点
  • 所有叶子节点在同一层(树的高度平衡)。
  • 每个节点(除了根节点),关键字数都在允许范围内。
    根节点:
    • 可以只有1个关键字(或更少,视具体定义而定),但一般至少有一个关键字,除非树为空。

具体阶数

  • 阶(阶数)为 m
  • 每个节点(除了叶子)至少有 ⌊m/2⌋ 个关键字(除了根)
  • 每个节点最多有 m-1 个关键字

结构特点

特性描述
多路每个内部节点可以有多个子节点(非二叉树)。
平衡所有叶子节点在同一层,保证查找、插入、删除的平均和最坏时间都 O(log n)。
关键字存储节点内存放有序的关键字,用于导航搜索。
节省空间由于多个关键字在一节点,减少树的高度,从而减少磁盘操作。

操作

  • 1. 查找
    • 从根节点开始,比较目标值与当前节点的关键字。
    • 根据比较结果,沿对应子节点递归查找。
    • 直到找到目标或到达叶子。
  • 2. 插入
    • 先找到插入位置(类似查找),在叶子节点插入。
    • 如果叶子已满(达到最大关键字数),则分裂:
      • 将中间关键字上升到父节点
      • 分裂成两个节点
    • 如果父节点也满,则递归向上分裂。
  • 3. 删除
    • 找到目标关键字所在节点:
      • 如果是叶子,直接删除。
      • 如果是内部节点,用前驱或后继节点替换,然后再删除叶子中的值。
    • 如果删除后节点关键字数少于最小(合规性),需要借兄弟节点或合并节点。

与B+树的区别

  • B树:所有节点(内部和叶子)都存关键字。
  • B+树:只有叶子存关键字,内部节点存索引,支持更高的查询效率。

实例

假设 m=4(阶为4):

  • 每个节点最多有 3 个关键字和 4 个子节点。
  • 每个非根节点至少有 2 个关键字(即⌊4/2⌋)。

简单的B树结构:

        [10, 20]/    |    \[5, 7]  [12, 15] [22, 25]
节点类型关键字子节点说明叶子或非叶子
根节点[10, 20]3个子节点:
- 小于10
- 10到20之间
- 大于20
非叶子
左子节点[5, 7]无子节点(叶子)
(如果它是叶子)
叶子
中左子节点[12, 15]无子节点(叶子)叶子
右子节点[22, 25]无子节点(叶子)叶子
  • 如果这是一个完整的B树,这些叶子可以在同一层,存放实际数据(例如:具体的元素值)。
  • 叶子节点中的关键字存放实际数据,或者指向存放数据的存储位置。
节点类型存放内容作用
内部节点(非叶子)索引/导航用的关键字引导搜索,决定下一步到哪个子节点
叶子节点存放实际数据或数据指针具体的数据存储点;支持范围查询和顺序扫描
  • 内部节点:
    • [10, 20],用来引导:<10,10到20,>20
  • 叶子节点:
    • [5, 7],[12, 15] ,[22, 25],存放实际数据元素。

总结

在这里插入图片描述

相关文章:

  • C++类继承详解:权限控制与继承方式解析
  • Gemini Pro 2.5 输出
  • AI 编程如何让你轻松采集网站数据?
  • 第二十一章:数据治理之数据安全:数据安全的驱动因素以及常见的数据安全举措
  • 阿姆斯特朗数
  • 五大要素协同效益的量化模型与实战策略
  • 【Qt开发】容器类控件
  • 真话与假话
  • Java集合框架详解:List、Set、Map及其实现类
  • C-内存函数,动态内存
  • 人工智能概念股:最新投资机会深度解析
  • 数字人教师:开启教育智慧革新之旅
  • 02_MQ常见问题
  • 网络编程--上篇
  • Minktec 柔性弯曲传感器,灵敏捕捉坐姿弓背、精准监测行走姿态,守护儿童背部健康,为科学健身提供数据支撑,开启职业健康与背痛 AI 干预新方向。
  • 将图层为shapefile类型的文件转成PostGis类型的详细实现步骤
  • java每日精进 5.27【异步实现】
  • SQL计算列
  • vue展示修改前后对比,并显示修改标注diff
  • YOLOv2 深度解析:目标检测领域的进阶之路
  • 网站开发代码交接文档书/网站查询关键词排名软件
  • 怎么用手机做网站编辑/百度推广的方式有哪些
  • 福州网上商城网站建设/个人微信管理系统
  • 洛阳网站建设建站系统/北京网站建设东轩seo
  • 昌平手机网站建设/搜索引擎营销的特点是什么
  • 自己用笔记本做网站/百度推广电话是多少