【高阶数据结构】B-数、B+树、B*树的原理

文章目录

  • B树的概念及其特点
  • 解析B树的基本操作
    • 插入数据
      • 插入数据模拟
    • 分析分裂如何维护平衡性
    • 分析B树的性能
  • B+树和B*树
    • B+树
      • B+树的分裂
      • B+树的优势
    • B*
      • B*树的分裂
  • 总结

B树的概念及其特点

B树是一颗多叉的平衡搜索树,广泛应用于数据库和 文件系统中,以保持数据有序并允许高效的插入、删除和查找操作。下面介绍B树的特点:

  • 多路平衡树:多路平衡树其实就是多叉平衡树每个节点都有多个指向孩子节点的指针以及键值。通常,一颗m阶的B树有k个子节点,有k-1个关键字,而k的取值范围为[ceil(m/2),m](celi表示向上取整)。例如一颗3阶的B树,最多有3个孩子2个关键字。
  • 键值有序:每个节点中包含多个关键字,这些关键字是有序的。节点中每个关键字都将子节点切割成两部分,左边部分的节点的所有关键字的值一定是小于该关键字的,右边节点的所有关键字的值都是大于该关键字的,这一点跟二叉搜索树的性质相同。
  • 树的高度平衡:所有叶子节点的深度都是一样的,站在AVL树的角度讲,每个节点的平衡因子都是0。具体如何维护这个平衡性下面会详细介绍。
  • 高效的磁盘读写:B树被设计用于在磁盘上高效的存储和读取数据。通过每个节点都有多个键值和多个字节的指针,从而减少磁盘的读写次数

下面给出一个3阶B树的节点示意图:
在这里插入图片描述
在设计B树节点时,孩子数量通常要多一个,这是为了方便后续实现插入操作和删除操作。概念上我们依旧认为m阶B树的节点的孩子个数为k个,实现的时候认为是k+1个。
我们将一个节点的所有键值集合称为数据域

解析B树的基本操作

插入数据

为了保证插入节点之后B树保持其平衡性,我们采用分裂节点来保持树的结构。具体的插入步骤如下:

  1. 查找插入位置:首先从根节点开始,找到应该插入新键值的叶子节点。(B树每一次插入新键值都一定在叶子节点处)
  2. 插入键值:在找到的叶子节点处插入新键值。如果该叶子节点的键值已经满了,即关键字的个数等于m+1,则需要对该叶子节点进行分裂。分裂的操作步骤如下:
    • 找到节点数据域的中间位置
    • 给一个新节点,将中间位置右边的所有数据(包括键值和孩子指针)搬到新节点中。新节点是被分裂节点的兄弟节点。
    • 将中间位置的键值移动放到父亲节点中,如果没有父节点,那就再创建一个父节点,并连接。

插入数据模拟

现在假设我们有一颗阶数为3的B树(每个节点最多有3个孩子和2个键值),并按以下顺序插入键值:10, 20, 5, 6, 12, 30, 7, 17。

  • 当插入了10、20之后:
    在这里插入图片描述
    只有一个节点,该节点已经有两个键值分别是10、20,现在这个节点的键值已经满了。
  • 插入5,节点键值溢出需要分裂:
    在这里插入图片描述
    仔细观察上述结果,根据插入数据的步骤,插入节点的键值满了,需要分裂。找到数据域的中间位置,也就是10的位置,10右边的数据全部移动到新兄弟节点中,再把中间键值10提取出来插入到父亲节点中。由于没有父节点,则新创建一个父节点。

点击观看分裂演示过程
点击观看整个插入过程

分析分裂如何维护平衡性

为什么分裂操作会保证B-树维持特性呢?以下是具体分析:

  • 保证叶子节点在同一深度:分裂只是在满节点的基础上进行的,将中间键提升到父节点并不会改变叶子节点的深度差,如果父节点满了,那父节点再分裂。如果父节点不存在,那么就会创建一个新父节点,此时这个新父节点一定成为了B树的根节点,也就意味着每条叶子节点分支的高度都会+1。
  • 控制节点的键值数量:每次分裂出去的键值数量都是大约一半,新的兄弟节点拥有的键值数量和被分裂节点的键值数量几乎一致。这样就保证了B树每个节点的键值数目在[ceil(m/2)−1,m−1]之间。
  • 分裂后有序:由于中间键值的选择,新的兄弟节点的所有键值一定都大于被分裂节点剩下的键值。再将中间键值插入到父节点中,中间键的左孩子指向被分裂节点,右孩子指向新兄弟节点,这样一来,整颗树还是一颗搜索树。

分析B树的性能

设n为B树的总键值数量,m为B树的阶数。则每个节点最多有m个孩子节点,m-1个关键字。

  • 查找效率:查找操作在B树中的时间复杂度为O(log n),原因如下:

    • B树的高度h和节点的最小度数t以及总键值数n的关系为:h=logt(n),因为每个节点至少有t个子节点。
    • 在每个节点中查找特定键值的时间复杂度为O(t),但由于t是一个常数,所以总时间复杂度就是O(1)。(t是B树的最小度数ceil(m/2),是确定的)
    • 查找的总时间效率就是树的高度乘每个节点查找特定键值的时间,也就是O(log n)
  • 插入操作:插入操作的时间复杂度也是O(log n),具体分析如下

    • 查找到插入位置的时间复杂度为O(logn)
    • 插入后可能需要分裂节点,分裂操作的时间复杂度为O(t),这是因为每个节点最多包含t个键值。
    • 由于树的高度较小且分裂操作是局部的,整体插入操作的时间复杂度仍为O(log n)。
  • 删除操作:删除操作的时间复杂度也是O(log n),具体分析:

    • 查找到目标节点的时间复杂度为O(log n)
    • 删除操作可能涉及节点的合并或键值的重新分配,这些操作的时间复杂度都是O(t),同样由于t是常数,总体的时间复杂度还是O(log n)

综上,B树各种操作时间效率都是logn。下面分析B树的空间复杂度:
B树的空间复杂度主要受到节点数目的影响。每个节点包含k-1个键值和k+1个子节点指针,节点总数与树的高度和阶数有关。由于B树是多路平衡树,其空间复杂度可以表示为O(n),其中n是键值总数。

B+树和B*树

B+树

B+树是B树的变形,在B树的基础上优化的多路平衡树,B+树的规则和B树类似,但在B树的基础上做了以下几点改进优化:

  • 分支节点的子节点指针数量和关键字的个数相同(或者是子节点数量比关键字个数多1)
  • 分支节点不存储实际的数据,只用于引导查找路径(存储的是孩子节点的最小关键字)
  • 所有的实际数据都存在叶子节点中
  • 叶子节点按照键值排序,彼此之间用一个指针连接,形成一个链表

下面给出一颗B+树结构示意图:
在这里插入图片描述
在B+树中如何查找一个数据呢?步骤如下:

和B树一致,从根节点开始逐层向下查找,比较当前键值和目标键值,如果大于目标键值,说明当前键值的孩子分支的所有值都大于目标键值。所以我们需要找到一个第一个大于目标键值的前一个键值种去寻找。点击演示B+树插入数据的动画。

B+树的分裂

当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针。

时间复杂度和空间复杂度和B数一样。

B+树的优势

  • 范围查询非常高效,因为叶子节点通过链表连接,可以顺序访问所有满足范围条件的节点。范围查询性能优于B树
  • 插入和删除操作相对简单一些,因为数据只存储在叶子节点中,只需在叶子节点中维护平衡
  • B+树适用于高效访问和顺序访问的场景

B*

B*树是B+树的变形,在B+树的非根和非叶子节点再增加指向兄弟节点的指针。具体结构如下:
在这里插入图片描述

B*树的分裂

当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针。所以,B*树分配新结点的概率比B+树要低,空间使用率更高

总结

  • B树:有序数组+平衡多叉树
  • B+树:有序数组链表+平衡多叉树
  • B*树:一棵更丰满的,空间利用率更高的B+树

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/772835.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu20.04突然没网的一种解决办法

本来要学一下点云地图处理,用octomap库,但是提示少了octomap-server库,然后通过下面命令安装的时候: sudo apt install ros-noetic-octomap-server 提示:错误:7 https://mirrors.ustc.edu.cn/ubuntu focal-security …

11 - matlab m_map地学绘图工具基础函数 - 绘制航迹、椭圆、风向玫瑰图和特定的圆形区域的有关函数及其用法

11 - matlab m_map地学绘图工具基础函数 - 绘制航迹、椭圆、风向玫瑰图和特定的圆形区域的有关函数及其用法 0. 引言1. 关于m_track2. 关于m_range_ring3. 关于m_ellipse4. 关于m_windrose5. 结语 0. 引言 本篇介绍下m_map中绘制航迹图函数(m_track)、绘…

HTTP与HTTPS协议区别及应用场景

HTTP(超文本传输​​协议)和 HTTPS(安全超文本传输​​协议)都是用于通过网络传输数据的协议。虽然它们有一些相似之处,但在安全性和数据保护方面也存在显著差异。 在这篇博文中,我们将探讨 HTTP 和 HTTPS…

Hadoop-11-MapReduce JOIN 操作的Java实现 Driver Mapper Reducer具体实现逻辑 模拟SQL进行联表操作

章节内容 上一节我们完成了: MapReduce的介绍Hadoop序列化介绍Mapper编写规范Reducer编写规范Driver编写规范WordCount功能开发WordCount本地测试 背景介绍 这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学…

利用YOLOv8识别自定义模型

一、背景介绍 最近项目需要识别自定义物品,于是学习利用YOLOv8算法,实现物品识别。由于物体类别不再常规模型中,因此需要自己训练相应的模型,特此记录模型训练的过程。 二、训练模型的步骤 1.拍照获取训练图片(训练图…

【前端CSS3】CSS显示模式(黑马程序员)

文章目录 一、前言🚀🚀🚀二、CSS元素显示模式:☀️☀️☀️2.1 什么是元素显示模式2.2 块元素2.3 行内元素2.4 行块元素2.5 元素显示模式的转换 三、总结🚀🚀🚀 一、前言🚀&#x1f…

操作符“->“

title: 操作符"->" date: 2024-01-16 00:00:00 categories: C箭头 tags: 箭头操作以及偏移量计算 #嘎嘎 操作符"->" ->是一个成员访问的操作,它的作用是通过一个指针来访问它所指向的对象的成员变量或成员函数。它的左边必须是一个指…

(vue)eslint-plugin-vue版本问题 安装axios时npm ERR! code ERESOLVE

(vue)eslint-plugin-vue版本问题 安装axios时npm ERR! code ERESOLVE 解决方法:在命令后面加上 -legacy-peer-deps结果: 解决参考:https://blog.csdn.net/qq_43799531/article/details/131403987

全网最适合入门的面向对象编程教程:09 类和对象的Python实现-类之间的关系,你知道多少?

全网最适合入门的面向对象编程教程:09 类和对象的 Python 实现-类之间的关系,你知道多少? 摘要: 本文主要对类之间的关系进行了基本介绍,包括继承、组合、依赖关系,并辅以现实中的例子加以讲解&#xff0…

Java的进程和线程

一Java的进程 二Java的线程 多线程 ◆如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为“多线程”。 ◆多个线程交替占用CPU资源,而非真正的并行执行。 ◆多线程好处。 ◆充分利用CPU的资源。 ◆简化编程模型。 ◆良好的用…

js 递归调用 相同对象--数组递归调用

<div class="save-cl"> <a-button @click="saveCl" >保存为常用策略</a-button> </div> saveCl(){ console.log(this.form.filterList[0],--------常用策略)// 此对象为上图对象 console.log(this.allElementsHaveValue(thi…

AGI系列(7)Reflection 在 AI agent 中的应用实例

斯坦福大学教授吴恩达一直非常推崇AI Agent,之前他提出过AI Agent的四种工作模式,分别是Reflection(反思)、Tool use(工具使用)、Planning(规划)和Multi-agent collaboration(多智能体协同)。 近日,他又开源了一个翻译 AI Agent, 他认为 AI 智能体机器翻译对改进传…

阿里巴巴Arthas分析调优JVM实战及常量池详解

目录 一、阿里巴巴Arthas详解 Arthas使用场景 Arthas命令 Arthas使用 二、GC日志详解 如何分析GC日志 CMS G1 GC日志分析工具 三、JVM参数汇总查看命令 四、Class常量池与运行时常量池 字面量 符号引用 五、字符串常量池 字符串常量池的设计思想 三种字符串操作…

掌握电路交换与分组交换:计算机网络的核心技术

计算机网络是现代信息社会的基石&#xff0c;而交换技术是实现网络通信的核心。本文将详细介绍两种典型的交换方式&#xff1a;电路交换和分组交换&#xff0c;帮助基础小白快速掌握这两种技术的基本概念和区别。 什么是电路交换&#xff1f; 电路交换&#xff08;Circuit Swi…

技术革新引领钢材质量智能化检测新纪元,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建钢材工业生产场景下钢材缺陷智能检测识别系统

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;其应用领域不断拓宽&#xff0c;正深刻改变着传统产业的运作模式。在钢材生产这一基础工业领域&#xff0c;AI的引入正为钢材的质量检测带来革命性的变革。 在传统的钢材生产流程中&#xff0c;质量检测是确…

【C++】二叉搜索树的模拟实现

前言&#xff1a;今天我们学习相对来说比前面轻松一点的内容&#xff0c;二叉搜索树&#xff0c;在之前我们学习过二叉树今天的内容对于我们就会比较简单一点了&#xff0c;一起加油。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质…

从零开始学量化~Ptrade使用教程——安装与登录

PTrade交易系统是一款高净值和机构投资者专业投资软件&#xff0c;为用户提供普通交易、篮子交易、日内回转交易、算法交易、量化投研/回测/实盘等各种交易工具&#xff0c;满足用户的各种交易需求和交易场景&#xff0c;帮助用户提高交易效率。 运行环境及安装 操作系统&…

计算机的错误计算(二十一)

摘要 两个不相等数相减&#xff0c;差为0&#xff1a; ? 在计算机的错误计算&#xff08;十九&#xff09;中&#xff0c;高中生小明发现本应为0的算式结果不为0. 今天他又发现对本不为0的算式&#xff0c;计算机的输出为0. 在 Python 中计算 &#xff1a; 则输出为0. 若用 C…

必备的 Adobe XD 辅助工具

想要高效便捷的使用 Adobe XD&#xff0c; Adobe XD 插件是必不可少的&#xff0c; Adobe XD 的插件非常多&#xff0c;但 90%都是英文&#xff0c;并且良莠不齐。在这儿挑选 9 个好用的 Adobe XD 插件给大家&#xff0c;这里是我整理的一些实用 Adobe XD 插件&#xff0c;让你…