B 树的简单认识
理解 B 树的概念
B 树是一种自平衡的查找树,能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除数据的动作,都能在对数时间内完成。
同一般的二叉查找树不同,B 树是一棵多路平衡查找树,其特性是:结点的孩子结点数可以多于两个,且每一个结点处可以存储多个元素。
在 B 树中,非叶子结点可以拥有可变数量的子结点,为了维持在预先设定的数量范围内,通常是对非叶子结点进行合并和分离。其优势是不需要像其他自平衡查找树那样频繁地重新保持平衡,其劣势是结点未被完全填充时会浪费一些空间。
特性
通常,我们会在 B 树的名称前添加阶数以示说明,如 m 阶 B 树。一个 m 阶的 B 树具有以下特性:
- 任意结点最多有 m 个孩子结点
- 任意除根结点以外的非叶子结点最少有 m2 个子结点
- 如果根结点不是叶子结点,那么它至少有 2 个孩子结点
- 有 k 个孩子结点的非叶子结点有 k-1 个键
- 所有的叶子结点都在同一层,B 树也是通过此约束来保持树的平衡
下述展示的是一个 3 阶 B 树:

变体
B 树可以指一个特定的树形结构,也可以指大体上的一类树形结构。
对于 B 树这一类树形结构,还包括了 B+ 树和 B* 树等结构,它们的简单定义如下:
对于 B+ 树,关键字只存储在叶子结点,非叶子结点存储的是叶子结点所存储关键字的部分拷贝,所有的叶子结点也都在相同的高度,叶子结点本身按关键字大小从小到大链接。
B* 树是 B+ 树的变体,在 B+ 树的基础上,非叶子结点(除根结点外)会增加指向同一层兄弟的指针,且非叶子结点关键字个数至少为 2m3,即块的最低使用率为 23(B+ 树为 12)。
下面为 B* 树的结构:

起源和运用
其实,B 树就是一种为磁盘而设计的树形结构,主要是降低其他树形结构访问磁盘的 IO 次数。
磁盘读取
从磁盘读取数据的时间主要涉及到“寻道时间”和“旋转延迟”:
- 寻道时间指的是磁盘接收到系统指令后,磁头从头开始移动到数据所在磁道所需要的时间,可能是 0 到 20 毫秒甚至更久
- 旋转延迟指的是寻道结束后,磁盘将对应的扇区旋转到磁头下所需要的时间,其平均时间大约在旋转周期的 50% 左右,对于一个 7200 转的磁盘,采用 60×1000÷7200 的公式计算得知一次旋转周期事件为 8.33 毫秒左右
磁盘的顺序读写会比随机读写快也是这个原因,在顺序读写时,磁头不需要再做寻道,仅需很少的旋转时间,而随机读写则需要不停地移动磁头寻找对应的磁道。
磁盘预读
为了尽量减少 IO 操作,计算机系统一般采取预读的方式,预读的长度一般为页(Page)的整数倍。
页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(多数操作系统页的大小为 4k),主存和磁盘以页为单位交换数据。
计算机系统是分页读取和存储的,每次读取和存取的最小单元为一页,而磁盘预读时通常会读取页的整数倍。
索引结构
对于文件系统和数据库系统的索引,通常以文件的形式存储在磁盘上,因此查找索引也会执行磁盘 IO 操作,如果查找过程中磁盘 IO 的存取次数过多会影响索引的效率。
数据库系统普遍使用 B 树或者 B+ 树作为索引结构,其巧妙地利用了磁盘预读原理,将一个结点设置为一个页的大小,这样每个结点只需要一次 IO 就可以完全载入。
同时,在使用过程中还运用了以下技巧:
- 每次新建结点时,直接申请一个页的空间,实现一个结点只需一次 IO
- 将根结点常驻内存,在实际使用时可以减少 1 次 IO
使用 B 树作为索引结构时,由于结点的大小等于一个页的大小,通常阶会比较大,因此树的深度较浅(通常不超过 3),查找效率非常高。
缺点
虽然数据库系统普遍使用 B 树作为索引结构,但是仍然有以下缺点:
- 非叶子结点直接存储数据,同一结点存储的索引数会比较少
- 数据即可能存储在叶子结点,也可能存储在非叶子结点,查询效率相对不稳定
- 在同层结点之间没有指针相邻,不适合做一些数据遍历操作
插入和删除
插入

B 树所有的插入过程都以根结点起始,首先是要查找到新元素所要存储的结点,然后判断插入结点的元素数量:
- 如果结点存储的元素数量小于最大值,那么有空间容纳新的元素,直接插入并保持结点内部有序即可;
- 如果结点存储的元素数量大于等于最大值,将它平均地分裂成 2 个结点:
- 从该结点的原有元素和新的元素中选择出中位数(按顺序排列的一组数据中居于中间位置的数);
- 小于中位数的元素放入左边结点,大于中位数的元素放入右边结点,中位数作为分隔值;
- 将分隔值插入到父结点中,这也可能会造成父结点发生分裂,父结点的分裂也可能会造成它的父结点分裂,以此类推;如果没有父结点,就创建一个新的父结点。
删除
删除 B 树中的结点有两种常用的策略:
- 定位并删除元素,然后调整树使它满足约束条件
- 从上到下处理这棵树,在进入一个结点之前,调整树使得其之后一旦遇到要删除的键,可以被直接删除而不需要再进行调整
对于前一种删除策略,其删除流程如下:
- 如果删除叶子结点中的元素,将它直接删除,如果结点中的元素数量小于最小值,则进行重新平衡操作;
- 如果删除非叶子结点中的元素,选择一个新的分隔值(左子树中最大的元素或右子树中最小的元素),将它从叶子结点中移除,替换掉被删除的元素作为新的分隔值,如果该叶子结点中的元素数量小于最小值,则进行重新平衡操作;
- 重新平衡操作从叶子结点开始,向根结点进行,直到树重新平衡。
在删除结点中,使 B 树重新平衡主要会有以下情况:
- 如果缺少元素结点的右兄弟结点存在且拥有多余的元素,那么向左旋转:
- 将父结点的分隔值移动到左子树中最大元素处;
- 将右兄弟结点的最小元素移动到原父结点的分隔值处;
- 如果缺少元素结点的左兄弟结点存在且拥有多余的元素,那么向右旋转:
3. 将父结点的分隔值移动到右子树中最小元素处;
4. 将左兄弟结点的最大元素移动到原父结点的分隔值处; - 如果缺少元素结点的两个直接兄弟结点都只有最小数量的元素,那么将它与左兄弟结点以及它们在父结点中的分隔值合并:
5. 将分隔值复制到左边的结点;
6. 将此缺少元素结点中的所有元素移动到左边结点;
7. 将缺少元素的结点移除;
8. 如果父结点是根结点且没有元素,则释放它并让合并后的结点成为新的根结点;如果父结点的元素数量小于最小值,重新平衡父结点。
对 B 树做删除元素的操作比较复杂,但仍然是以保持 B 树平衡为主,并且不使其导致特性失效。
相关文章:
B 树的简单认识
理解 B 树的概念 B 树是一种自平衡的查找树,能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除数据的动作,都能在对数时间内完成。 同一般的二叉查找树不同,B 树是一棵多路平衡查找树,其特性是ÿ…...
【大数据Hive3.x数仓开发】窗口函数案例:连续N次登录的用户;级联累加求和;分组TopN
文章目录1 统计连续N次登录的用户(N>2)自连接过滤实现窗口函数lead()实现2 级联累加求和自连接窗口函数sum()实现3 分组TopN问题对窗口函数的讲解part见:【大数据Hive3.x数仓开发】函数–窗口函数 1 统计连续N次登录的用户(N&…...
openpyxl库自动填充excel实例分享
openpyxl可以通过编写Python脚本实现自动化Excel操作,包括自动填充数据、格式化单元格、生成图表等操作。 以下是一个常见的自动化Excel操作示例: 自动填充数据: from openpyxl import Workbook from openpyxl.utils import get_column_l…...
ICLR2021清华团队做的知识蒸馏提升detector的点的工作paper 小陈读论文系列
这个作者栏目就是一个词 清爽 牛逼不需要花里胡哨哈哈 无疑是有点tian了哈哈 不重要 毕竟有机会研读 梦中情笑的paper 还是很感激的 真的 很清爽啊 很多KD的工作确实 在下游任务呢效果不是很好 然后就引出了自己的关于提升知识蒸馏在OD方面的工作 OD 首先就有两个问题 1.前…...
Java核心技术知识点笔记—集合框架
前言:Java最初版本只为最常用的数据结构提供了很少的一组类:Vector、Stack、Hashtable、BitSet和Enumeration接口。其中,Enumeration接口提供了一种用于访问任意容器中各个元素的抽象机制。与现代数据结构类库常见情况一样,Java集…...
Rsync数据同步工具
一、什么是Rsync Rsync是一款开源的,快速的,多功能的,可实现全量及增量(差异化备份)的本地或远程数据同步备份的优秀工具。 Rsync软件适用于Unix、Linux、Windows等多种操作系统。 (1)可使本地…...
redux小结
store.dispatch(action对象) 在 dispatch 中调用 action 方法返回 action 对象 // /actions/index.js /*** Action:* action本质上是一个 JS 对象;* 必须要包含 type 属性,否则会报错;* 只描述了有事情要发生,…...
【Python】【进阶篇】十、Pygame的Font文本和字体
目录十、Pygame的Font文本和字体10.1 font.SysFont()10.2 font.Font()10.3 字体对象方法十、Pygame的Font文本和字体 Pygame 通过pygame.font模块来创建一个字体对象,从而实现绘制文本的目的。 该模块的常用方法如下所示: 名称说明pygame.font.init()初…...
【从零开始学习 UVM】10.8、UVM TLM —— UVM TLM Example
文章目录 subComp1subComp2ComponentAsubComp3ComponentBTop Env/Test这个 UVM TLM 示例使用之前文章中讨论的 put 端口、TLM FIFO 和 get 端口来构建一个具有不同层次的 TLM 端口的测试台。 下面定义了一个名为Packet的类,作为从一个组件传输到另一个组件的数据项。这个类对象…...
获取自己所上传资源的下载量
import requestsurl = https://download-console-api.csdn.net/v1/user/sources/getUploadListByUserName?status=2&pageNum=1&pageSize=100 cookie = # 这里填自己的cookie header = {"authority": "download-console-api.csdn.net","met…...
Aspose.cells模板导出使用记录
简述 用Aspose.cells导出可以方便地将数据到Excel文档中,简单的直接将DataTable列表写入即可,复杂的格式一般会先做好模板,再将数据填充进去,这样可以保持设置好的样式,又能快速填充内容,十分方便。 智能…...
AcWing——糖果传递
有 n个小朋友坐成一圈,每人有 a[i]个糖果。 每人只能给左右两人传递糖果。 每人每次传递一个糖果代价为 1。 求使所有人获得均等糖果的最小代价。 输入格式 第一行输入一个正整数 n,表示小朋友的个数。 接下来 n 行,每行一个整数 a[i]&…...
Redis中的单线程模型
文章目录 文件事件处理器模型Redis的客户端与服务端的交互过程图Redis基于Reactor模式开发了自己的网络事件处理器,称之为 文件事件处理器(File Event Hanlder)。 文件事件处理器由Socket、IO多路复用程序文件事件分派器(dispather)事件处理器(handler)文件事件处理器模型 IO…...
Python函数默认参数设置(超级详细)
我们知道,在调用函数时如果不指定某个参数,Python 解释器会抛出异常。为了解决这个问题,Python 允许为参数设置默认值,即在定义函数时,直接给形式参数指定一个默认值。这样的话,即便调用函数时没有给拥有默…...
人工智能如何赋能业务创新?安克创新有话要说
对于一家企业来说,应该如何运用人工智能技术助力业务创新?作为一家多年复合增长率超过35%的企业,安克创新对这个话题无疑有着深切的体验感悟。飞速成长的消费电子企业众所周知,当下各行各业都在如火如荼地开展人工智能应用&#x…...
如何学习与学习的本质
如何学习两种模式两种记忆方式拖延问题学习方法学习本质两种模式 专注模式发散模式 专注模式和发散模式可以进行切换,提高效率, 发散模式可以后台工作。 两种记忆方式 工作记忆(前额叶皮质)长时记忆(图像比较容易记…...
C++ deque容器
C deque容器 文章目录C deque容器前言1. deque容器基本概念2. deque构造函数3. deque赋值操作4. deque大小操作5. deque 插入和删除6. deque 数据存取7. deque 排序总结前言 本文包含deque容器基本概念、deque构造函数、deque赋值操作、deque大小操作、deque插入和删除、deque…...
HashMap的底层原理
hashmap是一个以key,value形式存储的集合,在JDK1.7中是以数组链表的数据结构,在JDK1.8中是数组链表红黑树的数据结构,他在对数据操作时继承了数组的线性查找和链表的寻址修改 hashmap是线程不安全的 : 在JDK1.7中会造成环形链和数据丢失的情况 在JDK1.8中hashmap的put过程会造…...
Django 4.0文档学习(四)
上篇文章 Django 4.0文档学习(四) 文章目录编写你的第一个 Django 应用,第 6 部分自定义应用的界面和风格编写你的第一个 Django 应用,第 7 部分自定义后台表单自定义后台更改列表自定义后台界面和风格自定义后台主页编写你的第一…...
2023年全国最新高校辅导员精选真题及答案38
百分百题库提供高校辅导员考试试题、辅导员考试预测题、高校辅导员考试真题、辅导员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 112.为改变重知识传授轻能力培养的大学课堂,教学方法可以采用(&am…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
