5 分钟了解 B 树

640


大家好,前面那篇文章《3 分钟理解完全二叉树、平衡二叉树、二叉查找树》中我们了解了几种特殊的二叉树的功能及特点,知道了它们在进行查找数据时可以提高效率。

但需要注意的是,这是指在内存中进行查找。如果有海量的数据,不可能一次性读取到内存中,这时候就要考虑的是,如何在磁盘中快速找到需要的数据。

今天这篇文章中要介绍的“B 树”,它的使用场景是:查找磁盘中的大量数据。

B 树

B 树就是常说的“B 减树(B- 树)”,又名平衡多路(即不止两个子树)查找树,它和平衡二叉树的不同有这么几点:

  1. 平衡二叉树节点最多有两个子树,而 B 树每个节点可以有多个子树,M 阶 B 树表示该树每个节点最多有 M 个子树

  2. 平衡二叉树每个节点只有一个数据和两个指向孩子的指针,而 B 树每个中间节点有 k-1 个关键字(可以理解为数据)和 k 个子树( **k 介于阶数 M 和 M/2 之间,M/2 向上取整)

  3. B 树的所有叶子节点都在同一层,并且叶子节点只有关键字,指向孩子的指针为 null

和平衡二叉树相同的点在于:B 树的节点数据大小也是按照左小右大,子树与节点的大小比较决定了子树指针所处位置。

看着概念可能有点难理解,来看看图对比下平衡二叉树和 B 树。

对比平衡二叉树和 B 树

首先是节点, 平衡二叉树的节点如下图所示,每个节点有一个数据和最多两个子树:

640

B 树中的每个节点由两部分组成:

  1. 关键字(可以理解为数据)

  2. 指向孩子节点的指针

B 树的节点如下图所示,每个节点可以有不只一个数据,同时拥有数据数加一个子树,同时每个节点左子树的数据比当前节点都小、右子树的数据都比当前节点的数据大:

640

上图是为了方便读者理解 B 树每个节点的内容,实际绘制图形还是以圆表示每个节点。

了解了节点的差异后,来看看 B 树的定义,一棵 B 树必须满足以下条件

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

  2. 除根节点以外的所有非叶结点至少有 M/2 棵子树,至多有 M 个子树(关键字数为子树减一)

  3. 所有的叶子结点都位于同一层

用一张图对比平衡二叉树和 B 树:

640

可以看到,B 树的每个节点可以表示的信息更多,因此整个树更加“矮胖”,这在从磁盘中查找数据(先读取到内存、后查找)的过程中,可以减少磁盘 IO 的次数,从而提升查找速度。

B 树中如何查找数据

因为 B 树的子树大小排序规则,因此在 B 树中查找数据时,一般需要这样:

  1. 从根节点开始,如果查找的数据比根节点小,就去左子树找,否则去右子树

  2. 和子树的多个关键字进行比较,找到它所处的范围,然后去范围对应的子树中继续查找

  3. 以此循环,直到找到或者到叶子节点还没找到为止

B 树如何保证平衡

我们知道,平衡的树之所以能够加快查找速度,是因为在添加、删除的时候做了某些操作以保证平衡。

平衡二叉树的平衡条件是:左右子树的高度差不大于 1;而 B 树的平衡条件则有三点:

  1. 叶子节点都在同一层

  2. 每个节点的关键字数为子树个数减一(子树个数 k 介于树的阶 M 和它的二分之一

  3. 子树的关键字保证左小右大的顺序

也就是说,一棵 3 阶的 B 树(即节点最多有三个子树),每个节点的关键字数最少为 1,最多为 2,如果要添加数据的子树的关键字数已经是最多,就需要拆分节点,调整树的结构。

网上找到一张很不错的动图,我们来根据它分析下 B 树添加元素时如何保证平衡。

这个图用以表示往 4 阶 B 树中依次插入下面这组数据的过程:

6 10 4 14 5 11 15 3 2 12 1 7 8 8 6 3 6 21 5 15 15 6 32 23 45 65 7 8 6 5 4

640

建议放大图查看

由于我比较懒,我们来根据前几步分析下 B 树的添加流程:

  1. 首先明确:4 阶 B 树表示每个节点最多有 4 个子树、3 个关键字,最少有 2 个子树、一个关键字

  2. 添加 6,第一个节点,没什么好说的

  3. 添加 10,根节点最多能放三个关键字,按顺序添到根节点中

  4. 添加 4,还能放到根节点中

  5. 添加 14,这时超出了关键字最大限制,需要把 14 添加为子树,同时为了保证“所有叶子节点在同一层”,就需要拆几个关键字作为子树:



640


拆为:

640

这个拆的过程比较复杂,首先要确定根节点保留几个关键字,由于“非叶子节点的根节点至少有 2 棵子树”的限制,那就至少需要两个关键字分出去,又因为“子树数是关键字数+1”,如果根节点有两个关键字,就得有三个子树,无法满足,所以只好把除 6 以外的三个关键字都拆为子树。

谁和谁在一个子树上呢,根据“左子树比关键字小、右子树比关键字大”的规律,4 在左子树,10 和 14 在右子树。

继续添加 :

  1. 添加 5,放到 4 所在的子树上

  2. 添加 11,放在 10 和 14 所在的右子树上

  3. 添加 15,按大小应该放到 10、11 和 14 所在的子树上,但因为超过了关键字数限制,又得拆分

640

因为“根节点必须都在同一层”,因此我们不能给现有的左右子树添加子树,只能添加给 6 了;但是如果 6 有三个子树,就必须得有 2 个关键字,提升谁做关键字好呢,这得看谁做 6 中间的子树,因为右子树的所有关键字都得比父节点的关键字大,所以这个提升的关键字只能比未来右子树中的关键字都小,那就只有 10 和 11 可以考虑了。

提升 10 吧,没有比它小的做子树,那就只能提升 11 了:

640

再添加元素也是类似的逻辑:

  1. 首先考虑要插入的子树是否已经超出了关键字数的限制

  2. 超出的话,如果要插入的位置是叶子节点,就只能拆一个关键字添加到要插入位置的父节点

  3. 如果非叶子节点,就得从其他子树拆子树给新插入的元素做孩子

删除也是一样的,要考虑删除孩子后,父节点是否还满足子树 k 介于 M/2 和 M 的条件,不满足就得从别的节点拆子树甚至修改相关子树结构来保持平衡。

总之添加、删除的过程很复杂,要考虑的条件很多,具体实现就不细追究了,这里我们有个基本认识即可。

正是这个复杂的保持平衡操作,使得平衡后的 B 树能够发挥出磁盘中快速查找的作用。

使用场景

这部分摘自:浅谈算法和数据结构:平衡查找树之B树

文件系统和数据库系统中常用的B/B+ 树,他通过对每个节点存储个数的扩展,使得对连续的数据能够进行较快的定位和访问,能够有效减少查找时间,提高存储的空间局部性从而减少IO操作。他广泛用于文件系统及数据库中,如:

  1. Windows:HPFS 文件系统

  2. Mac:HFS,HFS+ 文件系统

  3. Linux:ResiserFS,XFS,Ext3FS,JFS 文件系统

  4. 数据库:ORACLE,MYSQL,SQLSERVER 等中

  5. 数据库:ORACLE,MYSQL,SQLSERVER 等




推荐阅读

我的自控力心得

读了本号称“App架构师实践指南”的书

Java 基础巩固5:全面理解自动装拆箱及常见风险点



640?


<think>嗯,用户查询的是三个技术名词的组合:smbus、ARP协议S5状态。这三个术语分别属于硬件接口、网络协议电源管理领域,看起来跨度挺大。用户可能是在调试某个嵌入式系统或服务器的网络唤醒功能?因为S5状态(软关机)下的设备通常需要网络唤醒支持,而ARP协议SMBus总线都可能参与这个过程。 先从SMBus开始梳理:这是Intel基于I2C开发的系统管理总线,主要用于低速设备通信。在服务器环境下,BMC(基板管理控制器)会通过SMBus监控硬件状态。用户提到这个,可能是想了解设备在S5状态下如何维持基础通信能力。 ARP协议这块需要特别注意应用场景。常规ARP用于IP-MAC地址解析,但在S5状态下,网卡通常只保留幻数据包监听功能。用户可能是遇到了网络唤醒失效的问题?需要提醒MAC地址过滤ARP缓存刷新这两个常见故障点。 S5状态(软关机)的电源特性很关键。虽然主系统断电,但+5VSB待机电源仍会供给网卡/BMC。这里可以关联到ACPI规范,特别是提到S5状态下允许的唤醒事件——包括PCIe唤醒网络唤醒。 突然想到一个可能的交叉场景:带外管理。企业级服务器的BMC通过SMBus收集传感器数据,当主机进入S5状态时,BMC仍可通过ARP响应网络查询。这或许就是用户真正关心的技术点?需要把这三者的协作关系说清楚。 最后生成的扩展问题要覆盖典型应用场景:网络唤醒配置问题、BMC功能验证、SMBus的设备配置——特别是Linux系统下的i2c-dev驱动使用。用户没提具体故障,所以补充了ARP欺骗防护这种延伸方向。</think>以下是关于SMBus、ARP协议S5状态的技术解析: ### 一、核心概念解析 1. **SMBus(系统管理总线)** 基于I²C的轻量级通信协议,用于主板设备管理(温度传感器、电池等)。特性包括: - 工作电压:3.3V(兼容5V设备) - 数据传输率:100kHz(标准模式) - 关键信号:SMBDATA(双向数据线)、SMBCLK(同步时钟) - 典型应用:ACPI电源管理、硬件监控 2. **ARP协议(地址解析协议)** 用于IP地址到MAC地址的动态映射: ```mermaid graph LR A[主机A] -->|广播ARP请求| B(局域网设备) B -->|单播ARP响应| A A --> 更新ARP缓存 ``` - 报文结构:28字节(硬件类型+协议类型+操作码+MAC/IP地址) - 缓存机制:条目通常存活15-20分钟 3. **S5状态(软关机)** ACPI电源状态的核心级别: | 状态 | 功耗 | 恢复方式 | 系统上下文 | |---|---|---|---| | S5 | 5-10W | 冷启动 | 完全丢失 | | vs S3 | 1-3W | 快速唤醒 | 内存保持 | ### 二、技术关联性 1. **SMBus与S5状态** - 在S5状态下,SMBus仍可由BMC(基板管理控制器)激活,实现带外管理 - 示例:服务器关机后通过IPMI指令`ipmitool power status`查询电源状态[^1] 2. **ARP与电源状态** - S5状态设备响应ARP的条件: - 网卡支持Wake-on-LAN(WOL) - BIOS启用PCIe唤醒功能 - 发送幻数据包(Magic Packet)到目标MAC ### 三、典型应用场景 1. **远程服务器管理** ```bash # 通过IPMI发送开机指令(依赖SMBus) ipmitool -H 192.168.1.10 -U admin power on ``` - 触发流程: `IPMI命令 → SMBus传输 → BMC唤醒主机 → ARP广播更新网关缓存` 2. **网络唤醒配置要点** - 硬件要求:支持WOL的网卡 - BIOS设置:启用`PCI Power Management``Resume by PCI Device` - 操作系统:Linux启用WOL `ethtool -s eth0 wol g` ### 四、故障排查指南 1. **S5状态无法唤醒** - 检测步骤: 1. 确认ACPI电源配置:`cat /sys/power/state` 2. 验证ARP缓存:`arp -a | grep 目标IP` 3. 检查SMBus连通性:`i2cdetect -l` 2. **ARP响应异常** - 解决方案: - 刷新ARP缓存:`arp -d 目标IP` - 启用ARP广播:`echo 1 > /proc/sys/net/ipv4/conf/all/arp_accept` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值