1 引言

B-tree,B即Balanced,是自平衡的多叉搜索树,用于组织和存储大量数据,以及数据库和文件系统等需要高效查找和插入操作的应用中。

为什么是“大量数据”?当主存不足以放入大量数据时,不常用的数据应存储于外存,而访问外存有额外时间开销(如磁盘转动时间、磁头移动时间等),于是我们需要一个数据结构来减少磁盘访问次数

B树每个节点包含多个关键字(键)和对应的数据指针(节点),关键字按照大小排序,并且每个节点的关键字都对应子节点的范围。

B树的根节点存储在主存中,而其他节点存储在磁盘或其他外部存储设备上。

M阶B树是有以下特性的M叉树:

  1. 数据项(data items)存储在叶节点(leaves);
  2. 非叶节点(nonleaf nodes)最多存储指引搜索路线的M-1个关键字Key,并且Key i是该节点子树i+1的最小值;
  3. 根节点(root)也是非叶节点,它有2至M个子节点;
  4. 所有非叶节点(root除外)有\(\lceil M/2 \rceil\)至M个子节点;
  5. 所有叶节点都位于最底层,有\(\lceil L/2 \rceil\)至L个数据项。L是指定值,由存储块和记录大小决定,即L=存储块大小/记录大小

五阶B树示例如下图所示:

上图中,M=5,L=5,于是,根节点有2到5个子节点,非叶节点最多有4个关键字,除根节点外的非叶结点有3到5个子节点,叶节点有3到5个数据项。每个节点都是一个磁盘块(disk block)

2 B树的操作

添加

如图2,插入57到图1。

插入操作步骤如下:

  1. 从根节点开始,按照键值的大小进行搜索,直到找到合适的叶子节点。在这个例子中,我们找到了可以插入57的叶子节点。
  2. 检查叶子节点是否已满。如果叶子节点未满,则可以直接将57插入到适当的位置。
  3. 如果叶子节点已满,需要进行节点的分裂操作。首先,将叶子节点中的数据项和新的数据项按照键值的顺序重新排序。然后,将前一半数据项保留在原始叶子节点中,将后一半数据项移动到新创建的叶子节点中。同时,更新父节点中的键值和分支信息,以反映新的叶子节点的存在。
  4. 如果父节点也已满,可能需要继续进行分裂操作,以保持B树的平衡性。

如图3,插入55到图2,共两步:分裂页节点和更新父节点。所以一共有三次disk write操作。

如图4,插入40到图3,由于父节点满项,所以除了分裂子节点,更新父节点,还需要再分裂父节点。一共五次disk write。

添加操作可能导致的根节点分裂是B树高度增加唯一方式。

删除

flowchart TD
A(寻找键值) ==> B{是否存在}
B ==是==> C[删除键值]
B ==否==> D(结束)
C ==> E{该节点是否符合最小占用}
E ==是==> D
E ==否==> F{邻居节点是否比最小占用多}
F ==是==> G[从邻居节点借一个]
F ==否==> H[合并邻居节点]
G ==> D
H ==> I{父节点是否符合最小占用}
I ==是==> D
I ==否==> J{是否为根节点}
J ==否==> F
J ==是==> K{根节点是否只有一个子节点}
K ==否==> D
K ==是==> L[删除根节点,子节点作为新根节点]
L ==> D

上图删除根节点是B树高度减小的唯一方式。

数据结构之B树的更多相关文章

  1. D&F学数据结构系列——B树(B-树和B+树)介绍

    B树 定义:一棵B树T是具有如下性质的有根树: 1)每个节点X有以下域: a)n[x],当前存储在X节点中的关键字数, b)n[x]个关键字本身,以非降序存放,因此key1[x]<=key2[x ...

  2. Go 数据结构--二分查找树

    Go 数据结构--二分查找树 今天开始一个Go实现常见数据结构的系列吧.有时间会更新其他数据结构. 一些概念 二叉树:二叉树是每个节点最多有两个子树的树结构. 完全二叉树:若设二叉树的高度为h,除第 ...

  3. 【经典数据结构】B树与B+树

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树 ...

  4. Linux 内核中的数据结构:基数树(radix tree)

    转自:https://www.cnblogs.com/wuchanming/p/3824990.html   基数(radix)树 Linux基数树(radix tree)是将指针与long整数键值相 ...

  5. 数据结构---平衡查找树之B树和B+树(转)

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 前面讲解了平衡查找树中的2-3树以及其实现红 ...

  6. 【经典数据结构】B树与B+树(转)

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树 ...

  7. 【经典数据结构】B树与B+树的解释

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 前面讲解了平衡查找树中的2-3树以及其实现红 ...

  8. 数据结构-PHP 线段树的实现

    转: 数据结构-PHP 线段树的实现 1.线段树介绍 线段树是基于区间的统计查询,线段树是一种 二叉搜索树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点.使用线段树可以快速的查 ...

  9. 算法数据结构(一)-B树

    介绍 B树的目的为了硬盘快速读取数据(降低IO操作次树)而设计的一种平衡的多路查找树.目前大多数据库及文件索引,都是使用B树或变形来存储实现. 目录 为什么B树效率高 B树存储 B树缺点 为什么B树效 ...

  10. [转]数据结构之Trie树

    1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tr ...

随机推荐

  1. 2022-09-04:以下go语言代码输出什么?A:不能编译;B:45;C:45.2;D:45.0。 package main import ( “fmt“ ) func main() {

    2022-09-04:以下go语言代码输出什么?A:不能编译:B:45:C:45.2:D:45.0. package main import ( "fmt" ) func main ...

  2. 又一个开源便斩获 7k star 的新模型「GitHub 热点速览」

    Star 并不能代表什么,但是绝对能表示一个项目的受欢迎程度.就像刚开源一周就有 7k+ star 的新模型,输入文本 / 图像就能获得 3D 对象.除了这个新模型,本周还有一款新的 Web 3D 渲 ...

  3. 使用 @GrpcClient 实现客户端

    转载请注明出处: @GrpcClient 注解的作用是将 gRPC 客户端注入到 Spring 容器中,方便在应用程序中使用 gRPC 客户端调用 gRPC 服务提供的函数.使用 @GrpcClien ...

  4. js有关dom操作学习

    dom对象就是操作网页的document dom节点: 整个文档是一个文档节点(document对象) 每个 HTML 元素是元素节点(element 对象) HTML 元素内的文本是文本节点(tex ...

  5. .NET周报 【5月第4期 2023-05-27】

    国内文章 C#使用词嵌入向量与向量数据库为大语言模型(LLM)赋能长期记忆实现私域问答机器人落地之openai接口平替 https://www.cnblogs.com/gmmy/p/17430613. ...

  6. Galaxy Project 是一个由 NIH、NSF、Johns Hopkins University 等机构支持的开源生物医学开源项目。Galaxy 作为其中的一个子项目,提供了以英文为主,......

    本文分享自微信公众号 - 生信科技爱好者(bioitee).如有侵权,请联系 support@oschina.cn 删除.本文参与"OSC源创计划",欢迎正在阅读的你也加入,一起分 ...

  7. CMake个人理解和使用

    前言 CMake是一个构建工具,通过它可以很容易创建跨平台的项目.通常使用它构建项目要分两步,通过源代码生成工程文件,通过工程文件构建目标产物(可能是动态库,静态库,也可能是可执行程序).使用CMak ...

  8. The content of element type “web-app“ must match 解决方法

    报错原因 ‍ 问题描述 : 在创建 SpringMVC 时 , 选用 idea 的 webapp 模板来创建 , xml 配置文件中进行配置时发现提示警告 警告如下: ‍ ​ ​ 这错误大概的意思就是 ...

  9. 在Linux环境下通过命令行执行JMeter脚本后查看响应结果的配置

    在Linux环境中进行性能测试时,我们可能会遇到一定程度的报错.如果无法打开JMeter的GUI界面,但又需要查看响应结果,可以按照以下步骤进行配置: 1. 打开JMeter的安装目录,在`bin/` ...

  10. Oracle分组取最大值

    需求 该SQL是一个子SQL,需要查询出某个人所有过往履历中职务最高的 SELECT a."EMP_ID",a."CADRE_LEVEL" FROM (SELE ...