B-树特点以及插入、删除数据过程

B树(B-Tree)是一种自平衡的多路查找树,它广泛应用于数据库索引和文件系统中,尤其适用于外部存储设备(如磁盘)。B树的设计使得它能够高效地存储大量数据并支持高效的插入、删除和查询操作。以下是B树的主要特点,详细解释其结构和行为:

特点

1. 多路平衡树

B树是一个多路平衡查找树,不同于传统的二叉树。它的每个节点可以有多个子节点,而不仅限于两个。具体来说,B树的阶数(degree)决定了每个节点的子节点的数量上限。

  • 阶数(m):B树的阶数m是一个重要的参数,表示每个节点最多可以有m个子节点,最多可以存储m-1个键值;父节点最少2个子节点,1一个元素;非父节点最少可以有[m/2]个子节点,[m/2]-1个元素。 注意[m/2]向上取整。
  • 节点结构:每个节点包含多个元素和指向子节点的指针。例如,阶数为m的B树中,一个节点最多包含m-1个键值和m个子节点指针。节点的元素按升序排列,子节点指针在元素之间。
  • 键值:每个节点保存若干个数据项(键),这些键在节点内按升序排列。
  • 指针:每个节点有若干个指针,指向其子节点。一个包含k个键的节点,会有k+1个指针。

2. 平衡性

B树保证了树的平衡性——所有叶子节点都在同一层。这意味着树的高度保持平衡,不会出现偏向某一边的情况,因此,B树能够提供对数时间的查找、插入和删除操作。

  • 高度平衡:从根到任意叶子节点的路径长度相同。这是B树在性能上优于一般二叉树的一个重要特性。因为高度较小,B树的查找效率很高。

3. 有序性

B树的节点内存储的数据是有序的,并且节点之间也保持严格的顺序关系。具体地:

  • 节点内的键值是按升序排列的。
  • 对于节点的每个子节点指针,指向的子树中的键值均满足:
  • 子节点左边的键值小于当前节点的键值。
  • 子节点右边的键值大于当前节点的键值。
  • 这种有序性使得B树能够高效地进行范围查询和逐个访问数据。

4. 每个节点最多存储多个键

B树的每个节点可以存储多个键,这意味着B树的每个节点能够包含大量的数据。这一特点使得B树可以在减少树的高度的同时,增加单次磁盘I/O操作的数据量,从而提高查询效率。

  • 节点的最大容量:在阶数为m的B树中,每个节点最多包含m-1个键。节点的最小容量(也就是每个节点最少存储的键数)为⌈m / 2⌉ - 1个键。
    例如,阶数为3的B树(m=3),每个节点最多存储2个键(即m-1),每个节点至少存储1个键(即⌈m / 2⌉ - 1)。

插入数据

B树的插入操作详解

B树的插入操作用于将一个新的元素插入到树中的适当位置,并确保B树的平衡性。在插入过程中,B树保持自平衡的特性,确保所有叶子节点都在同一层,并且每个节点的键数量不超过规定的最大值,同时不低于最小值。如果插入操作导致节点超出了容量,就会触发节点分裂操作。

插入操作步骤

B树插入操作可以分为几个主要步骤:

  1. 查找插入位置
    首先,进行标准的查找操作,找到待插入元素应插入的位置。插入位置是在叶子节点中,B树通过比较每个节点内的键值确定插入位置。如果目标键值已存在,则不进行插入(具体行为取决于实现方式,有的实现会更新已有元素)。

  2. 在叶子节点插入元素
    一旦找到了适当的插入位置(即叶子节点),并且该叶子节点有足够的空间(即未达到节点的最大容量),我们直接将新的元素插入到该叶子节点中。

  3. 检查是否需要分裂
    如果插入的元素使叶子节点的元素数目超过最大容量(即达到m个键值),则需要进行节点分裂操作。分裂过程的关键是:

    • 将该节点的中间元素移到父节点。
    • 将节点分裂成两个子节点,一个包含左半部分的键,另一个包含右半部分的键。
  4. 递归分裂父节点(如有需要)
    分裂操作会将中间元素推送到父节点。如果父节点也满了(即包含了m-1个键值),则需要递归地对父节点进行分裂,直到找到一个可以容纳新元素的节点。如果根节点也被分裂,则树的高度会增加。

  5. 根节点分裂
    如果根节点发生分裂,树的高度会增加,新的根节点会创建出来,并包含分裂后的两个子节点和一个键值。这样,树的高度增加了一层。

插入操作的详细步骤与图示

以阶数为3的B树为例,假设一个B树的阶数m=3,即每个节点最多可以存储2个元素,最多有3个子节点。初始树如下所示:

        [10]
       /    \
   [5]       [15]

假设我们要插入元素7

  1. 查找插入位置
    从根节点[10]开始,7小于10,因此进入左子树[5]。由于7大于5,插入位置就是[5]节点中。

  2. 插入元素到叶子节点
    将元素7插入到叶子节点[5]中,得到:

    [5, 7]
    
  3. 检查是否需要分裂
    节点[5, 7]包含2个元素,未超过最大容量,因此无需分裂。

插入后的树仍然是平衡的,没有改变结构:

        [10]
       /    \
   [5, 7]    [15]
插入导致节点分裂的情况

假设我们现在要插入元素3,并继续使用阶数m=3的B树。当前树结构为:

        [10]
       /    \
   [5, 7]    [15]
  1. 查找插入位置
    从根节点[10]开始,3小于10,进入左子树[5, 7]。由于3小于5,插入位置就是[5, 7]节点的左边。

  2. 插入元素到叶子节点
    将元素3插入到叶子节点[5, 7],得到:

    [3, 5, 7]
    
  3. 检查是否需要分裂
    节点[3, 5, 7]已经包含3个元素,超过了该节点的最大容量(2个元素)。因此,节点需要分裂。

  4. 节点分裂

    • 将节点[3, 5, 7]分裂为两个节点:
      • 左边节点[3]
      • 右边节点[7]
    • 将中间元素5上移到父节点[10]

分裂后的树结构如下:

        [5, 10]
       /    |    \
   [3]    [5]    [7, 15]

插入操作完成,树的结构发生了改变,原先的叶子节点被分裂,父节点也增加了一个元素。

递归分裂操作

在一些情况下,插入操作可能导致父节点也满了,进而需要递归分裂。假设我们现在有一个阶数为m=3的B树,当前结构如下:

            [20]
           /    \
     [10, 15]    [25, 30]

我们要插入元素17

  1. 查找插入位置
    从根节点[20]开始,17小于20,进入左子树[10, 15]。由于17大于15,插入位置是[10, 15]节点的右边。

  2. 插入元素到叶子节点
    将元素17插入到叶子节点[10, 15]中,得到:

    [10, 15, 17]
    
  3. 检查是否需要分裂
    节点[10, 15, 17]包含3个元素,超过了节点的最大容量(2个元素),因此需要分裂。

  4. 节点分裂

    • 将节点[10, 15, 17]分裂为两个节点:
      • 左边节点[10, 15]
      • 右边节点[17]
    • 将中间元素15上移到父节点[20]

此时,父节点[20]变为[15, 20],树结构变为:

            [15, 20]
           /    |    \
     [10]    [15]    [17, 25, 30]

注意,这里[20]的父节点分裂后增加了新的元素。

总结

B树的插入操作包含以下几个核心步骤:

  1. 查找插入位置:通过树的层级结构,从根节点到叶子节点进行查找,确定插入位置。
  2. 插入元素:如果目标叶子节点有空间,直接插入元素。
  3. 节点分裂:如果插入导致节点超出最大容量,将节点分裂并将中间元素推送到父节点。
  4. 递归分裂:如果父节点也满了,递归地进行分裂,直到找到可以容纳元素的父节点,或者根节点发生分裂,增加树的高度。

在这里插入图片描述

插入操作保证了B树的平衡性,使得查询、插入和删除操作始终保持对数时间复杂度O(log n)。

删除数据

B树的删除操作详解

B树的删除操作不仅需要删除目标元素,还要保证树的平衡性。删除操作可能会导致节点的元素数量低于最小容量,这时需要通过借用合并操作来恢复树的平衡。

B树的删除操作可以分为以下几个步骤:

  1. 查找待删除元素:首先通过标准的查找操作找到要删除的元素。
  2. 删除元素:如果待删除的元素在叶子节点,直接删除;如果在内部节点,则需要借用或合并来处理。
  3. 借用或合并节点:删除元素后,某些节点可能会变得“不满”(即元素数少于最小容量),需要通过借用兄弟节点的元素或将当前节点与兄弟节点合并来维持B树的性质。

具体步骤和情况如下:

B树删除操作的基本步骤

1. 删除叶子节点的元素
  • 如果待删除的元素位于叶子节点,并且该节点中元素的数量大于或等于B树规定的最小数量(即⌈m / 2⌉ - 1个键),可以直接删除该元素。
  • 不需要进行合并或借用,树结构不会发生变化。
2. 删除内部节点的元素

如果待删除的元素位于非叶子节点,情况就更复杂,通常有以下几种处理方式:

  • 替换删除元素:首先,找到待删除元素的前驱或后继元素(通常是该节点左子树的最大元素或右子树的最小元素),并将其替换待删除的元素。然后,删除该前驱或后继元素。这转化为一个在叶子节点删除元素的问题。
  • 删除替代元素并调整:一旦替代元素被删除,我们可以继续执行删除操作,并根据需要调整树的结构。
3. 恢复树的平衡

删除元素后,如果某个节点的元素数小于最小数量(即节点的键数小于⌈m / 2⌉ - 1),则需要恢复树的平衡性。常见的恢复方法包括:

  • 借用操作:从相邻的兄弟节点借用元素。如果兄弟节点有多余的元素,借用一个元素并将其父节点的元素下移。借用后的兄弟节点和当前节点会重新调整,保持平衡。
  • 合并操作:如果相邻的兄弟节点没有多余的元素可借用,则需要将当前节点与兄弟节点合并,合并后的节点元素数会增加,父节点的元素数减少。如果父节点的元素数低于最小数量,则继续向上调整。

删除操作的各种情况

我们通过一个阶数为m = 3的B树来逐步讲解删除操作的不同情况。

示例B树结构

假设当前的B树结构如下(阶数为3,最多可以存储2个元素):

              [30]
             /    \
     [10, 20]      [40, 50]
      /    \        /    \
  [5]      [15]  [35]   [45, 60]

假设我们需要删除元素20

情况一:删除叶子节点的元素
  • 查找位置:元素20位于叶子节点[10, 20]中。
  • 删除:删除20后,节点变为[10],此时该节点的元素数大于或等于最小容量(即1个元素,满足最小容量2个元素的一半),因此无需调整树结构。
              [30]
             /    \
     [10]          [40, 50]
      /    \        /    \
  [5]      [15]  [35]   [45, 60]
情况二:删除内部节点的元素,且使用替代

假设我们需要删除元素30,这个元素位于根节点。

  1. 查找替代元素:为了删除30,我们找到30前驱元素,即其左子树的最大元素20,然后将20替换掉30
  2. 删除替代元素:元素20已经被删除,原来的节点[10, 20]成为[10]
  3. 由于没有发生分裂和合并,树的结构保持不变。

最终树结构变为:

              [20]
             /    \
     [10]          [40, 50]
      /    \        /    \
  [5]      [15]  [35]   [45, 60]
情况三:删除元素导致节点不满,借用兄弟节点的元素

假设我们删除元素15,它位于叶子节点[5, 15]

  1. 查找元素并删除:删除元素15后,节点[5]剩余一个元素,已经少于最小容量(1个元素,最小容量应该是1个元素)。
  2. 借用兄弟节点:我们可以借用右兄弟节点[20]中的元素,将其右边的元素20移动到父节点30中,并将父节点的指针更新。这样,节点[5]会得到补充,变为[5, 10]

树结构如下:

              [30]
             /    \
     [5, 10]       [40, 50]
      /    \        /    \
  [5]      [15]  [35]   [45, 60]
情况四:删除元素导致节点不满,合并操作

假设我们删除元素5,元素5位于[5, 10]

  1. 查找位置并删除:删除5后,节点[10]只剩下1个元素,低于最小容量,需要恢复平衡。
  2. 合并操作:由于右兄弟[15]有元素,可以进行合并。我们将[10][15]合并为一个节点[10, 15]
  3. 更新父节点:父节点[30]中,1015会更新为30,但是由于节点合并没有变化,所以树的结构将被调整。

树结构如下:

              [30]
             /    \
    [10, 15]        [40, 50]
      /    \        /    \
  [5]      [15]  [35]   [45, 60]
总结

B树的删除操作涉及多个复杂的步骤,包括查找、删除、借用、合并等。具体的删除操作可以分为以下几种情况:

  1. 删除叶子节点元素:直接删除元素,不需要额外的操作。
  2. 删除非叶子节点元素:通过替换删除元素为前驱或后继元素,然后删除该元素。
  3. 借用兄弟节点:如果删除元素导致节点元素数量少于最小容量,可以从兄弟节点借用元素来平衡树。
  4. 合并节点:如果借用不可行,节点会与兄弟节点合并,且父节点会相应地调整。

B树的删除操作保证了树的平衡,使得树的高度保持在对数级别,查找、插入和删除操作的时间复杂度都为O(log n)。

在这里插入图片描述

视频参考链接:https://www.bilibili.com/video/BV1JU411d7iY?vd_source=8e9f9cfdea4ecad3b0fa1ad660d5ab18&spm_id_from=333.788.videopod.sections

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

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

相关文章

自定义反序列化过程

需求&#xff1a;student对象中name属性&#xff0c;序列化时将该属性映射为stuname&#xff0c;反序列化时将 Json中的NAME键值对映射到name属性中 AllArgsConstructorNoArgsConstructorGetterSetterstatic class Student {JsonProperty("stuname")private List<…

解读 ConcurrentHashMap 源码:探索高并发场景下的卓越性能

ConcurrentHashMap 了&#xff0c;作为线程安全的 HashMap &#xff0c;它的使用频率也是很高。那么它的存储结构和实现原理是怎么样的呢&#xff1f;HashMap 源码&#xff1a;揭开哈希表背后的秘密 1、ConcurrentHashMap 1.7 1. 存储结构 Java 7 中 ConcurrentHashMap 的存储…

为什么配置TIM11作为系统时基的时候会出现__NVIC_PRIO_BITS

回想起当初学freertos的时候&#xff0c;某个中断优先级以下的任务是不能被freertos管理的&#xff08;好像是全是抢占优先级&#xff0c;0子优先级的设置&#xff09;。当初还不是非常了解。只知道管理不了 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {RCC_ClkI…

数字IC实践项目(10)—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证(付费项目)

数字IC实践项目&#xff08;10&#xff09;—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证&#xff08;付费项目&#xff09; 前言项目框图1&#xff09;DDR4 Verification IP2&#xff09;DDR4 JEDEC Model & Tb 项目文件1&#xff09;DDR4 Veri…

python解析网页上的json数据落地到EXCEL

安装必要的库 import requests import pandas as pd import os import sys import io import urllib3 import json测试数据 网页上的数据结构如下 {"success": true,"code": "CIFM_0000","encode": null,"message": &quo…

wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器

嗨&#xff0c;大家好&#xff0c;我是小华同学&#xff0c;关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 wflow-web是一个开源的工作流设计器&#xff0c;它支持可视化拖拽表单组件&#xff0c;动态任意层级结构审批节点&#xff0c;以及复杂流程条件的设置…

adobe acrobat 安装中文支持

win11英文语言导致adobe没中文支持 参考这里 做了安装里面还有一个fix 中文ocr的 我的系统是英文的 我发现adobe配置里无法修改 系统apps里去修改安装程序 中文简体功能及附属能力都安装到系统里但是安装后&#xff0c;还是没有&#xff1a; 按照ctl &#xff0c;然后点击…

每日小题--买股票的最佳时机

目录 题目 分析 解题思路 完整代码 题目 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润…

AUTOSAR_EXP_ARAComAPI的7章笔记(3)

☞返回总目录 相关总结&#xff1a;AutoSar AP简单多绑定总结 7.3 多绑定 如在 5.4.3 小节中简要讨论的&#xff0c;某个代理类 / 骨架类的不同实例之间的技术传输是不同的&#xff0c;多绑定描述了这种情况的解决方案。多种技术原因都可能导致这种情况出现&#xff1a; 代…

Xcode 16 pod init失败的解决方案

目录 前言 一、错误重现 二、解决方案 1.右击项目修改文件展示方式 2.修改.xcodeproj文件 3.参考文档 前言 我们使用Xcode创建新项目之后&#xff0c;执行pod init报错。我们看一下如何解决。 一、错误重现 RuntimeError - PBXGroup attempted to initialize an object …

MySQL联合索引(abc)命中测试

1.建表 mysql创建一张表&#xff0c;表名&#xff1a;‘test_models’ id列为 主键&#xff0c;int类型 &#xff0c;自增a,b,c,d,e 全部是int&#xff08;11&#xff09;为&#xff08;a,b,c&#xff09;添加一个联合索引 index_abc 执行语句&#xff1a;创建表 CREATE TA…

ssm药房管理系统—计算机毕业设计源码42430

目 录 摘要 1 绪论 1.1课题目的及意义 1.2研究背景 1.3 研究方法 1.4论文结构与章节安排 2 药房管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.…

pgSQL-timescaledb复制表出现的问题

今日在工作中&#xff0c;需要复制一张timescaledb表&#xff0c;pgAdmin上复制一直未成功&#xff0c;或者我找错位置了。 1.我使用Navicate连接pgSQL&#xff0c;连上后选中相应表&#xff0c;右键复制结构即可 2.复制结构后&#xff0c;到pgAdmin中&#xff0c;将对应表下的…

CSP/信奥赛C++语法基础刷题训练(8):洛谷P5718:找最小值

CSP/信奥赛C语法基础刷题训练&#xff08;8&#xff09;&#xff1a;洛谷P5718&#xff1a;找最小值 题目描述 给出 n n n 和 n n n 个整数 a i a_i ai​&#xff0c;求这 n n n 个整数中最小值是什么。 输入格式 第一行输入一个正整数 n n n&#xff0c;表示数字个数。…

恒源云使用手册记录:从服务器下载数据到本地

文章目录 一、xftp下载二、通过Xftp客户端连接站点 一、xftp下载 先下载xftp&#xff1a;下载连接 二、通过Xftp客户端连接站点 右击文件&#xff0c;点击新建 名称可以任意 主机、端口号、用户名 点击这里的复制登录命令 比如我这里得到ssh -p 41604 rooti-2.gpushare.co…

电子工牌独立双通道定向拾音方案(有视频演示)

现在一些行业的客服人员在面对客户都要求使用电子工牌分别记录客服和顾客的声音,我们利用双麦克风阵列双波束拾音的方案设计了一个电子工牌方案.可以有效分别记录客服和顾客的声音. 方案思路: 我们采用了一个双麦阵列波束拾音的模块A-59,此模块可以利用2个麦克风组成阵列进行双…

Elasticsearch 和 Kibana 8.16:Kibana 获得上下文和 BBQ 速度并节省开支!

作者&#xff1a;来自 Elastic Platform Product Team Elastic Search AI 平台&#xff08;Elasticsearch、Kibana 和机器学习&#xff09;的 8.16 版本包含大量新功能&#xff0c;可提高性能、优化工作流程和简化数据管理。 使用更好的二进制量化 (Better Binary Quantizatio…

亮数据——助力全球数据抓取的高效代理平台

目录 实际案例&#xff1a;利用代理服务抓取企业信息完整代码运行结果 亮数据的技术优势与应用场景产品更新&#xff1a;简化注册流程与智能助手升级立即注册&#xff0c;开启您的数据抓取之旅&#xff01; 在如今的大数据时代&#xff0c;企业决策越来越依赖于数据分析&#x…

使用win32com将ppt(x)文件转换为pdf文件

本文来记录下如何使用win32com将ppt(x)文件转换为pdf文件 文章目录 win32com概述win32com优缺点代码实例本文小结 win32com概述 Pywin32 是一个用于与 Microsoft Windows 操作系统交互的 Python 扩展模块&#xff0c;它提供了对多个 Windows API 的访问&#xff0c;包括对 Mic…

Win11专业版Docker安装、配置记录

零&#xff0c;系统环境配置 首先&#xff0c;安装Docker需要系统支持开启硬件虚拟化及Hyper-V功能&#xff0c;所以这里需要Win10/11的专业版&#xff0c;这样才能进行Docker for Windows软件安装。 1&#xff0c;硬件虚拟化 至于如何开启硬件虚拟化&#xff0c;自行百度即…