【数据结构与算法】B树与B+树

news2024/11/24 22:13:56

🔥 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:数据结构与算法
🌠 首发时间:2022年12月6日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾
🌟 一以贯之的努力 不得懈怠的人生

阅读指南

  • B树
  • B树的插入
  • B树的删除
  • B+树
  • B树 VS B+树

B树

在这里插入图片描述

B B B 树,又称为多路平衡查找树, B B B 树中所有结点的孩子个数的最大值称为 B B B 树的阶,通常用 m m m 表示,上图即为 5 5 5 B B B 树。一棵 m m m B B B 树或为空树,或为满足如下特性的 m m m 叉树:

  1. 树中每个结点至多有 m m m 棵子树,即至多含有 m − 1 m - 1 m1 个关键字

  2. 若根结点不是终端结点,则至少有两棵子树

  3. 除根结点外的所有非叶结点至少有 ⌈ m / 2 ⌉ \lceil m/2 \rceil m/2 棵子树,即至少含有 ⌈ m / 2 ⌉ − 1 \lceil m/2 \rceil - 1 m/21 个关键字

  4. 所有的叶结点都出现在同一层次上,并且不带信息(可以视为外部结点或类似于折半查找判定树的查找失败结点,实际上这些结点并不存在,指向这些结点的指针为空)

  5. 所有非叶结点的结构如下:
    在这里插入图片描述

    其中, K i   ( i = 1 , 2 , . . . , n ) K_i \ (i = 1, 2, ..., n) Ki (i=1,2,...,n) 为结点的关键字,且满足 K 1 < K 2 < . . . < K n K_1 < K_2 < ... < K_n K1<K2<...<Kn P i   ( i = 0 , 1 , . . . , n ) P_i \ (i = 0, 1, ..., n) Pi (i=0,1,...,n) 为指向子树根结点的指针,且指针 P i − 1 P_{i-1} Pi1 所指子树中所有结点的关键字均小于 K i K_i Ki P i P_{i} Pi 所指子树中所有结点的关键字均大于 K i K_i Ki n   ( ⌈ m / 2 ⌉ − 1 ≤ n ≤ m − 1 ) n \ (\lceil m/2 \rceil - 1 \leq n \leq m - 1) n (m/21nm1) 为结点中关键字的个数

m m m B B B 树的核心特性:

  1. 根结点的子树数 ∈ [ 2 , m ] \in [2, m] [2,m],关键字数 ∈ [ 1 , m − 1 ] \in [1, m - 1] [1,m1];其他结点的子树数 ∈ [ ⌈ m / 2 ⌉ , m ] \in [\lceil m/2 \rceil, m] [m/2,m],关键字数 ∈ [ ⌈ m / 2 ⌉ − 1 , m − 1 ] \in [\lceil m/2 \rceil -1, m - 1] [m/21,m1]
  2. 对于任一结点,其所有子树的高度都相同
  3. 关键字的值:子树 0 < 0 < 0< 关键字 1 < 1 < 1< 子树 1 < 1 < 1< 关键字 2 < 2 < 2< 子树 2 < 2 < 2< . . . ... ... (类比二叉查找树 左 < < < < < < 右)

问:含 n n n 个关键字的 m m m B B B 数,最小高度和最大高度是多少?

最小高度 —— 让每个结点尽可能地满,每个结点都有 m − 1 m-1 m1 个关键字, m m m 个分叉,则可以得到公式 n ≤ ( m − 1 ) ( 1 + m + m 2 + m 3 + . . . + m h − 1 = m h − 1 n \leq (m - 1)(1 + m + m^2 + m^3 + ... + m^{h - 1} = m^h - 1 n(m1)(1+m+m2+m3+...+mh1=mh1,因此 h ≥ l o g m ( n + 1 ) h \geq log_m(n + 1) hlogm(n+1)

最大高度 —— 让各层的分叉尽可能地少,即根结点只有 2 2 2 个分叉,其他结点只有 ⌈ m / 2 ⌉ \lceil m/2 \rceil m/2 个分叉,各层结点至少有:第一层 1 1 1、第二层 2 2 2、第三层 2 ⌈ m / 2 ⌉ . . . 2 \lceil m/2 \rceil ... 2m/2... h h h 2 ( ⌈ m / 2 ⌉ ) h − 2 2 (\lceil m/2 \rceil)^{h - 2} 2(m/2)h2,第 h + 1 h + 1 h+1 层共有叶子结点(失败结点) 2 ( ⌈ m / 2 ⌉ ) h − 1 2 (\lceil m/2 \rceil)^{h - 1} 2(m/2)h1

n n n 个关键字的 B B B 树必有 n + 1 n + 1 n+1 个叶子结点,则 n + 1 ≥ 2 ( ⌈ m / 2 ⌉ ) h − 1 n + 1 \geq 2 (\lceil m/2 \rceil)^{h - 1} n+12(m/2)h1,即 h ≤ l o g ⌈ m / 2 ⌉ n + 1 2 + 1 h \leq log_{\lceil m/2 \rceil} \frac{n + 1}{2} + 1 hlogm/22n+1+1

我们可以用表格的形式更直观地来计算最大高度:

k = ⌈ m / 2 ⌉ k = \lceil m/2 \rceil k=m/2

层数最少结点数最少关键字数
第一层 1 1 1 1 1 1
第二层 2 2 2 2 ( k − 1 ) 2(k - 1) 2(k1)
第三层 2 k 2k 2k 2 k ( k − 1 ) 2k(k - 1) 2k(k1)
第四层 2 k 2 2k^2 2k2 2 k 2 ( k − 1 ) 2k^2(k - 1) 2k2(k1)
h h h 2 k h − 2 2k^{h-2} 2kh2 2 k h − 2 ( k − 1 ) 2k^{h-2}(k - 1) 2kh2(k1)

从表格中我们可以得到: h h h 层的 m m m B B B 树至少包含关键字总数 1 + 2 ( k − 1 ) ( k 0 + k 1 + k 2 + . . . + k h − 2 = 1 + 2 ( k h − 1 − 1 ) 1 + 2(k -1)(k^0 + k^1 + k^2 + ... + k^{h - 2} = 1 + 2(k^{h - 1} - 1) 1+2(k1)(k0+k1+k2+...+kh2=1+2(kh11)

若关键字总数少于这个值,则高度一定小于 h h h,因此 n ≥ 1 + 2 ( k h − 1 − 1 ) n \geq 1 + 2(k^{h - 1} - 1) n1+2(kh11),得: h ≤ l o g k n + 1 2 + 1 = l o g ⌈ m / 2 ⌉ n + 1 2 + 1 h \leq log_{k} \frac{n + 1}{2} + 1 = log_{\lceil m/2 \rceil} \frac{n + 1}{2} + 1 hlogk2n+1+1=logm/22n+1+1

所以含 n n n 个关键字的 m m m B B B 数, l o g m ( n + 1 ) ≤ h ≤ l o g ⌈ m / 2 ⌉ n + 1 2 + 1 log_m(n + 1) \leq h \leq log_{\lceil m/2 \rceil} \frac{n + 1}{2} + 1 logm(n+1)hlogm/22n+1+1

B树的插入

核心要求:

  • 对于 m m m B B B 树 —— 除根结点外,结点关键字个数 ⌈ m / 2 ⌉ − 1 ≤ n ≤ m − 1 \lceil m/2 \rceil - 1 \leq n \leq m- 1 m/21nm1
  • 子树 0 < 0 < 0< 关键字 1 < 1 < 1< 子树 1 < 1 < 1< 关键字 2 < 2 < 2< 子树 2 < 2 < 2< . . . ... ...

构建 B B B 树时,如果在插入新的关键字后,导致原结点的关键字数超过上限,则从中间位置( ⌈ m / 2 ⌉ \lceil m/2 \rceil m/2)将其中的关键字分为两部分,左部分包含的关键字放在原结点中,右部分包含的关键字放到新结点中,中间位置( ⌈ m / 2 ⌉ \lceil m/2 \rceil m/2)的结点插入原结点的父结点;若此时导致其父结点的关键字个数也超过了上限,则继续进行这种分裂操作,直至这个过程传到根结点为止,进而导致 B B B 树高度增 1 1 1

每次插入新元素一定是插入到最底层 “终端结点”,用 “查找” 来确定插入位置

B树的删除

① 若被删除的关键字在终端结点,则直接删除该关键字即可(注意结点关键字个数是否低于下限 ⌈ m / 2 ⌉ − 1 \lceil m/2 \rceil - 1 m/21

② 若被删除的关键字在非终端结点,则用直接前驱或直接后继来替代被删除的关键字

  • 直接前驱:当前关键字左侧指针所指子树中 “最右下” 的元素
  • 直接后继:当前关键字右侧指针所指子树中 “最左下” 的元素

所以对非终端结点关键字的删除必然可以转化为对终端结点的删除操作

③ 兄弟够借。若被删除的关键字所在结点删除前的关键字个数低于下限,且与此结点右(或左)兄弟结点的关键字个数还很宽裕,则需要调整该结点、右(或左)兄弟结点及其双亲结点(父子换位法)

④ 兄弟不够借。若被删除的关键字所在结点删除前的关键字个数低于下限,且此时与该结点相邻的左、右兄弟结点的关键字个数均 = ⌈ m / 2 ⌉ − 1 = \lceil m/2 \rceil - 1 =m/21,则将关键字删除后与左(或右)兄弟结点及双亲结点中的关键字进行合并

在合并过程中,双亲结点中的关键字个数会减 1 1 1。若其双亲结点是根结点且关键字个数减少至 0 0 0(根结点关键字个数为 1 1 1 时,有 2 2 2 棵子树),则直接将根结点删除,合并后的新结点成为根;若双亲结点不是根结点,且关键字个数减少到 ⌈ m / 2 ⌉ − 2 \lceil m/2 \rceil - 2 m/22,则又要与它自己的兄弟结点进行调整或合并操作,并重复上述操作,直至符合 B B B 树的要求为止

B+树

在这里插入图片描述

上图是一棵 4 4 4 B + B+ B+

一棵 m m m B + B+ B+ 树需满足下列条件:

  1. 每个分支结点最多有 m m m 棵子树(孩子结点)
  2. 非叶根结点至少有两颗子树,其他每个分支结点至少有 ⌈ m / 2 ⌉ \lceil m/2 \rceil m/2 棵子树
  3. 结点的子树个数与关键字个数相等
  4. 所有叶结点包含全部关键字及指向相应记录的指针,叶结点中将关键字按大小顺序排序,并且相邻叶结点按大小顺序相互连接起来
  5. 所有分支结点中仅包含它的各个子结点中关键字的最大值及指向其子结点的指针

B树 VS B+树

m m m B B B 树:

  • 结点中的 n n n 个关键字对应 n + 1 n + 1 n+1 棵子树
  • 根结点的关键字数 n ∈ [ 1 , m − 1 ] n \in [1, m-1] n[1,m1],其他结点的关键字数 n ∈ [ ⌈ m / 2 ⌉ − 1 , m − 1 ] n \in [\lceil m/2 \rceil - 1, m - 1] n[m/21,m1]
  • B B B 树中,各结点中包含的关键字是不重复的
  • B B B 树的结点中都包含了关键字对应的记录的存储地址

m m m B + B+ B+ 树:

  • 结点中的 n n n 个关键字对应 n n n 棵子树
  • 根结点的关键字数 n ∈ [ 1 , m ] n \in [1, m] n[1,m],其他结点的关键字数 n ∈ [ ⌈ m / 2 ⌉ , m ] n \in [\lceil m/2 \rceil, m] n[m/2,m]
  • B + B+ B+ 树中,叶结点包含全部关键字,非叶结点中出现过的关键字也会出现在叶结点中
  • B + B+ B+ 树中,叶结点包含信息,所有非叶结点仅起索引作用,非叶结点中的每个索引项只含有对应子树的最大关键字和指向该子树的指针,不含有该关键字对应记录的存储地址

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑e盘不见了怎么恢复?6个步骤找回e盘

电脑e盘不见虽然不是一件常见的事&#xff0c;但是也会有发生的情况。虽然我们还有其他磁盘&#xff0c;平时也会经常忽略e盘。但是e盘也是一个存储磁盘&#xff0c;当电脑e盘不见了&#xff0c;我们也会想要找回来。那么电脑里的e盘丢失了怎么找回呢&#xff1f;下面我们就一起…

QListWidget::itemEntered无效

利用QListWidget进行数据列表的展示&#xff1b; &#xff08;1&#xff09;初始化一个QListWidget&#xff1a; QListWidget* newListWidget new QListWidget(parent); newListWidget->setResizeMode(QListView::Adjust); newListWidget->setViewMode(QListView::Icon…

论文浅尝 | AdaLoGN: 基于推理的机器阅读理解的自适应逻辑图网络

笔记整理&#xff1a;何仕玉珑&#xff0c;天津大学硕士链接&#xff1a;https://arxiv.org/pdf/2203.08992.pdf动机最近的机器阅读理解数据集(如ReClor和LogiQA)需要对文本执行逻辑推理。传统的神经模型不足以进行逻辑推理&#xff0c;而符号推理机不能直接应用于文本推理。为…

【Cross-Direction and Progressive Network:交叉的挖掘信息】

A Cross-Direction and Progressive Network for Pan-Sharpening &#xff08;一种交叉递进的泛锐化网络&#xff09; 本文提出了一种交叉方向渐进&#xff08;cross-direction and progressive&#xff09;网络CPNet来解决全色锐化问题。对信息的充分处理是我们模型的主要特…

实战三十一:基于LightGCN推荐算法的推荐系统详细教程(代码+数据)

推荐系统任务描述:通过用户的历史行为(比如浏览记录、购买记录等等)构造出用户-项目交互图,协同过滤利用过去的用户-项目交互来实现预测;对相似的用户进行推荐相同喜好的item,帮助他们发现可能感兴趣的却不容易发现的item;同时将埋没在长尾中的好商品推荐给可能感兴趣的…

01-go基础-05-数组(声明数组、数组赋值、遍历数组、数组值修改)

文章目录1. 声明数组- 语法- 完整示例2. 数组赋值- 语法- 完整示例- 未赋值的元素仍为默认值3. 数组元素赋值- 语法- 示例4. 数组访问4.1 访问数组中元素4.2 遍历数组5. 数组的修改5.1 修改全部数组元素值5.2 修改单个元素值5.3 数组长度不可以更改1. 声明数组 - 语法 语法 …

刷爆力扣之1 比特与 2 比特字符

刷爆力扣之1 比特与 2 比特字符 HELLO&#xff0c;各位看官大大好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 今天阿呆继续记录下力扣刷题过程&#xff0c;收录在专栏算法中 &#x1f61c;&#x1f61c;&#x1f61c; 该专栏按照不同类别标签进行刷题&am…

[附源码]Python计算机毕业设计Django四川景区管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Go语言的IO库那么多纠结该如何选择

在Go语言中I/O操作的内置库有很多种&#xff0c;比如:io库&#xff0c;os库&#xff0c;ioutil库&#xff0c;bytes库&#xff0c;strings库等等。 io.Reader/Writer Go语言里使用io.Reader和io.Writer两个 interface 来抽象I/O&#xff0c;他们的定义如下。 type Reader int…

数据图表软件-FineReport控件简介

1. 概述 1.1 版本 报表服务器版本 功能变更 11.0 -- 1.2 应用场景 在帆软报表的具体应用中&#xff0c;经常使用「控件」来实现不同的功能。根据使用方式可将控件分为填报控件和参数控件两大类&#xff0c;填报时使用的控件为填报控件&#xff0c;参数界面使用的控件为参…

认证服务------遇到的问题及解决方案

认证服务的问题及解决方案 问题1&#xff1a;发送验证码 发送验证码要注意的问题 发送验证码要注意的两个问题 1、接口防刷 接口防刷就是因为发送验证码的api接口是可以通过查看页面元素看的到的 上面就可以看到发送验证码的js代码中的请求地址&#xff0c;可以恶意的通过…

【产品设计】APP提升用户注册率的五个方案探讨结论

首先介绍下前置条件&#xff0c;我们在做产品时&#xff0c;出于一开始对行业特征和用户参与度的考虑&#xff0c;所以对注册没有要求&#xff0c;当用户触发需要记录用户行为的功能时才会弹出登陆注册的聚合页面&#xff0c;能够触发弹出的功能有&#xff1a;赞、写点评、回复…

ActiveMQ 笔记(九)Windows部署:单机与集群部署流程

1. 单机版部署 版本关系说明:JDK8环境只能安装5.2及以下的。超过5.2需要JDK9及以上版本环境。 (1)官网下载安装包 activemq.apache.org 选择一个版本进行下载, (2)解压安装包 下载完成之后解压 下载后直接解压缩直接就能用(免安装)。 bin/是服务启动相关的命令文件…

Xylan-PEG-NHS|木聚糖-聚乙二醇-琥珀酰亚胺

Xylan-PEG-NHS|木聚糖-聚乙二醇-琥珀酰亚胺 琥珀酰亚胺又称为丁酰亚胺或丁二酰亚胺&#xff0c;是一种无色针状结晶或具有淡褐色光泽的薄片固体&#xff0c;味甜。易溶于水、醇或氢氧化钠溶液&#xff0c;不溶于醚、氯仿等 中文名称&#xff1a;木聚糖-聚乙二醇-琥珀酰亚胺 …

目标检测 YOLOv5 开源代码项目-环境配置问题

学习视频&#xff1a; 目标检测 YOLOv5 开源代码项目调试与讲解实战【土堆 x 布尔艺数】 项目源码&#xff1a;ultralytics / yolov5 教程&#xff1a;手把手带你调参Yolo v5 (v6.2)&#xff08;推理&#xff09; 遇到的问题&解决的链接&#xff1a; ERROR: Failed buil…

怎样查看对方计算机网络密码,如何查看邻居家的wifi密码?不知道wifi密码怎么蹭网...

如何查看邻居家的wifi密码&#xff1f;不知道wifi密码怎么蹭网&#xff1f;不知道大家有没有遇到这样的问题&#xff1a;手机虽然已经连接到了WiFi&#xff0c;但是却已经忘记了WiFi密码。这时候如果会有一丝担忧在心中&#xff0c;如果下次连接不上&#xff0c;或是有人问你密…

[C语言数据结构]树

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录1.树1.1树的概念&#xff1a;1.2树与非树1.3一些关于树的概念&#xff1a;1.4树的一些表示方法&#xff1a;2.二叉树2.1概念&#xff1a;2.2二叉树的特点2.3满二叉树…

为什么在做微服务设计的时候一定需要DDD?

记得之前在规划和设计微服务架构的时候&#xff0c;张队长给了我一个至今依然记忆深刻的提示&#xff1a;你的设计蓝图里为什么没有看到DDD的影子呢&#xff1f; 随着对充血模型的领域认知的加深&#xff0c;我越加感觉到DDD的重要性。于是网上一顿海找&#xff0c;并做了学习…

Thinkpad x13 锐龙安装 Archlinux 记录

硬件配置&#xff1a; 笔记本影响cpu显卡内存硬盘ThinkPad X13 锐龙版r7 4750U核显16g1TB 山寨固态&#xff08;大华&#xff09;镜像准备 https://archlinux.org/download/ http://mirrors.163.com/archlinux/iso/2022.12.01/ 每次安装都检查iso镜像是否是网站最新的&#x…

国外数字书籍第2期

1、高级FPGA设计 (中英文版) 本书主要讲解了FPGA设计、方法和实现。这本书略去了不太必要的理论、推测未来的技术、过时工艺的细节&#xff0c;用简明、扼要的方式描述FPGA中的关键技术。 图1 高级FPGA设计 (克里兹)(英文版)主要内容包括&#xff1a;设计速度高、体积小、功耗低…