相关笔记

概览

  • B树是为磁盘等外部存储设计的一种平衡搜索树,核心目标是最小化磁盘I/O次数
  • 每个节点可包含多个关键字多个孩子指针,节点大小设计为匹配磁盘页大小
  • 由参数最小度t(minimum degree)控制,每个节点最多 个关键字,最少 个关键字
  • 所有叶子节点在同一层,保证树的高度为
  • 红黑树吸收红色子节点后,等价于==最小度t=2的B树==(即2-3-4树)

知识结构总览

flowchart TD
    A["B树的定义"] --> B["动机:磁盘I/O优化"]
    A --> C["最小度 t 的定义"]
    A --> D["B树的5条基本性质"]
    A --> E["高度分析"]
    A --> F["节点存储结构"]
    A --> G["与红黑树的关系"]

    B --> B1["磁盘访问 ≈ 内存访问的 10^5 倍"]
    B --> B2["减少树高 = 减少磁盘I/O"]
    B --> B3["节点大小 = 磁盘页大小"]

    C --> C1["t ≥ 2"]
    C --> C2["控制分支因子范围"]

    D --> D1["性质1:每个节点最多 2t-1 个关键字"]
    D --> D2["性质2:根至少 1 个关键字"]
    D --> D3["性质3:其他节点至少 t-1 个关键字"]
    D --> D4["性质4:所有叶子在同一层"]
    D --> D5["性质5:节点关键字有序排列"]

    E --> E1["最小节点数 → 高度上界"]
    E --> E2["h ≤ log_t((n+1)/2)"]
    E --> E3["最大关键字数:(2t)^(h+1) - 1"]

    F --> F1["key[1..n]:关键字数组"]
    F --> F2["c[1..n+1]:孩子指针数组"]
    F --> F3["leaf:叶标志"]
    F --> F4["n:当前关键字数"]

    G --> G1["吸收红色子节点"]
    G --> G2["得到最小度 t=2 的B树"]
    G --> G3["即 2-3-4 树"]

核心思想

2.1 为什么需要B树?

核心思路

B树的核心设计思想是”用空间换I/O”:将二叉搜索树的每个节点从存储1个关键字扩展为存储多个关键字,使每个节点恰好填满一个磁盘页(通常4KB或16KB)。这样,每次磁盘I/O就能读取大量关键字信息,从而将树的高度大幅降低,将搜索所需的磁盘I/O次数从 降到 (其中 远大于2)。

类比理解:想象你在图书馆找一本书。

  • 二叉搜索树就像每层楼只有2个房间,每个房间只放1本书的索引卡片。要找到目标书,你需要在很多层楼之间跑来跑去。
  • B树就像每层楼有几十个房间,每个房间放满索引卡片。你只需去很少几层楼就能找到目标书。

虽然每个房间(节点)更大了,但因为你一次性读取整个房间(一次磁盘I/O读取整个磁盘页),所以效率反而更高。

具体数据对比

参数二叉搜索树/红黑树B树(t=200)
每个节点关键字数1100~399
n=100万时树高约20约3~4
每个节点大小几十字节约40KB
磁盘页利用率极低(大量浪费)高(每页一个节点)
搜索磁盘I/O次数约20次约4次

2.2 最小度t的定义

最小度(minimum degree)

B树的最小度 是一个整数参数,它控制B树的分支因子(branching factor)。

  • 每个节点最多有 个孩子(即最多 个关键字)
  • 每个非根节点至少有 个孩子(即至少 个关键字)
  • 根节点至少有 个孩子(即至少 个关键字),除非树中只有根节点本身

为什么 如果 ,则每个非根节点至少有 个关键字(),这意味着节点可以是空的,这与B树的定义矛盾。此外, 时每个节点最多只有 个关键字,退化为二叉搜索树,失去了B树的优势。

2.3 B树的5条基本性质

B树的定义

一棵==最小度为 的B树是满足以下性质的有根树==:

性质1:每个节点 具有以下属性:

  • :当前存储在节点 中的关键字个数
  • 个关键字 升序排列
  • :一个布尔值,当 叶节点时为 TRUE,当 内部节点时为 FALSE

性质2:每个内部节点 包含 个孩子指针 。叶节点没有孩子。

性质3:关键字 的各子树的关键字范围分隔开:

  • 如果 是子树 中任意一个关键字,则: 且对于

性质4:所有叶节点具有相同的深度(即树的高度 )。

性质5:B树满足以下关于关键字数量的约束:

  • 根节点:至少包含 个关键字
  • 其他每个节点:至少包含 个关键字
  • 每个节点:最多包含 个关键字(因此最多有 个孩子)。当一个节点恰好有 个关键字时,称该节点为满的(full)

节点关键字与孩子数的关系

这是因为 个关键字将搜索空间划分为 个区间,每个区间对应一棵子树。

2.4 B树的高度分析

高度上界的推导

B树的高度 与存储的关键字总数 之间的关系可以通过以下步骤推导:

下界分析(最小节点数)

  1. 根节点至少有 个孩子(除非 ),每个孩子至少有 个关键字。
  2. 层(根)至少有 个节点,至少 个关键字。
  3. 层至少有 个节点,每个至少 个关键字,共至少 个关键字。
  4. 层至少有 个节点,每个至少 个关键字,共至少 个关键字。
  5. 一般地,第 层()至少有 个节点。

因此,一棵高度为 的B树中,关键字总数 满足:

解出

上界分析(最大关键字数)

每层每个节点最多有 个关键字,最多有 个孩子。

  • 层(根): 个节点,最多 个关键字
  • 层:最多 个节点,最多 个关键字
  • 层:最多 个节点,最多 个关键字

总关键字数:

2.5 节点存储结构

B树节点的磁盘表示

一个B树节点 在磁盘上的存储格式如下:

字段含义大小
当前存储的关键字个数1个整数
个关键字,升序排列 个关键字
个孩子指针 个磁盘地址
是否为叶节点1个布尔值

在实际实现中, 数组通常分配固定大小 ,以避免动态分配。

2.6 与红黑树的关系

红黑树与B树的等价性

将一棵红黑树中每个红色节点与其黑色父节点合并(即”吸收”红色子节点),得到的结构恰好是一棵==最小度 的B树,也称为2-3-4树==。

  • 黑色节点对应B树中的一个关键字
  • 红色节点被吸收到其黑色父节点中,使该B树节点可以包含1、2或3个关键字(对应原来的2-3-4节点)
  • 红黑树的黑高度对应B树的高度
  • 红黑树的旋转操作对应B树的==分裂与合并操作**

对应关系

红黑树结构B树等价结构
黑节点(无红色子节点)含1个关键字的B树节点
黑节点 + 1个红色子节点含2个关键字的B树节点
黑节点 + 2个红色子节点含3个关键字的B树节点

补充理解与拓展

3.1 B树的发明历史

B树由 Rudolf BayerEdward M. McCreight 于1972年提出,论文发表于 Acta Informatica

Bayer, R. & McCreight, E. (1972). “Organization and Maintenance of Large Ordered Indexes”. Acta Informatica, 1(3): 173-189.

历史背景:Bayer当时在波音公司(Boeing)工作,为大型数据库系统设计高效的索引结构。有趣的是,论文中从未解释”B”的含义——业界普遍认为”B”代表Boeing(公司名)、Bayer(发明者姓氏)或Balanced(平衡),但作者本人从未确认。McCreight在2009年的访谈中表示,B并没有特定含义,更多是因为当时论文中已经用了A、C等字母。

3.2 B树变体族谱

B树自1972年提出以来,衍生出多种重要变体:

变体提出者/年份核心改进来源
B+树Comer, 1979所有数据存储在叶节点,叶节点用链表连接;内部节点仅存索引Comer, D. (1979). “The Ubiquitous B-Tree”. ACM Computing Surveys, 11(2): 121-137
B*树Knuth, 1973非根节点至少 个关键字,节点更满,空间利用率更高Knuth, D.E. (1973). The Art of Computer Programming, Vol. 3: Sorting and Searching
Bw树Levandoski et al., 2013无锁乐观并发控制,使用CAS操作代替 latch,适合多核SSDLevandoski, J.J., Lomet, D.B., & Sengupta, S. (2013). “The Bw-Tree: A B-tree for New Hardware Platforms”. VLDB, 6(11): 1081-1092
Cache-Oblivious B树Bender et al., 2000不依赖硬件缓存参数,自动适应任意层级的内存层次Bender, M.A., Demaine, E.D., & Farach-Colton, M. (2000). “Cache-Oblivious B-Trees”. FOCS, 499-509

3.3 B树 vs 红黑树:磁盘I/O视角

维度红黑树B树(t=200)
树高(n=100万)约20层约3-4层
每节点大小几十字节~几百字节约40KB(匹配磁盘页)
磁盘页利用率极低(一页可放数百节点但只读一个)高(一页恰好一个节点)
搜索I/O次数O(h) ≈ 20次O(h) ≈ 4次
适用场景内存数据结构磁盘/SSD数据结构
插入/删除复杂度O(log n) CPUO(t log_t n) CPU + O(h) I/O

关键洞察:红黑树在磁盘上的效率低下的根本原因是节点太小。一个4KB的磁盘页可以容纳数百个红黑树节点,但搜索时每次I/O只读取一个节点,其余空间全部浪费。B树通过让每个节点恰好填满一个磁盘页,实现了I/O带宽的充分利用

3.4 现代应用场景

B树及其变体在现代计算机系统中无处不在:

  • 文件系统

    • NTFS(Windows):主文件表(MFT)使用B+树组织
    • HFS+(macOS):目录索引使用B+树
    • ext4(Linux):目录索引使用htree(基于B树思想的哈希B树)
  • 数据库索引

    • MySQL InnoDB:B+树,16KB页大小
    • PostgreSQL:B树索引
    • Oracle:B+树索引
  • 键值存储

    • LevelDB/RocksDB:LSM-Tree(写优化,与B树互补)
    • MongoDB:B树索引
    • SQLite:B树,页大小可配置(默认4KB)

易混淆点与辨析

常见误区

误区1:“B树就是二叉树(Binary Tree)的缩写” 错误。B树的”B”含义不明(可能代表Boeing、Bayer或Balanced),与Binary无关。B树是多路搜索树,不是二叉树。

误区2:“B树的t值越大越好” 不完全正确。t越大,树高越低,I/O次数越少;但节点内搜索时间 也越大。最优t值需要平衡磁盘I/O成本和CPU搜索成本(见18.2节习题18.2-7)。

误区3:“B树的所有节点都必须是满的” 错误。B树只要求节点至少 个关键字(根至少1个),不要求满。节点可以是半满的,这是B树插入/删除操作的基础。

误区4:“B树和B+树是同一种数据结构” 错误。B+树是B树的重要变体,区别在于:B+树的所有数据(关键字+卫星数据)都存储在叶节点,内部节点仅存储索引关键字;叶节点之间通过指针连接形成有序链表,支持高效的范围查询。

误区5:“最小度t=1也是合法的B树” 错误。t=1时,非根节点至少 个关键字,这意味着节点可以为空,违反B树的定义。此外,t=1时B树退化为二叉搜索树,失去了多路搜索的优势。


习题精选

习题概览

题号题目难度考察要点
18.1-1为什么不允许t=1?基础B树定义的边界条件
18.1-2图18.1的合法t值基础最小度约束
18.1-3t=2时{1,2,3,4,5}的所有合法B树中等B树结构枚举
18.1-4高度h的B树最多存储多少关键字基础高度上界推导
18.1-5红黑树吸收红色子节点中等红黑树与B树的等价性

详细解答

18.1-1 为什么最小度t=1不是B树的合法值?

如果 ,根据B树的性质5:

  • 每个非根节点至少包含 个关键字
  • 每个节点最多包含 个关键字

这意味着非根节点可以是空的(0个关键字),这与B树作为搜索树的定义矛盾。此外, 时每个节点最多1个关键字,B树退化为二叉搜索树,失去了多路搜索树减少I/O的核心优势。

从数学角度看, 时高度上界公式 无意义( 未定义)。

18.1-2 图18.1中的B树,合法的最小度t值有哪些?

图18.1中的B树,根节点有1个关键字,内部节点最多有3个关键字。

根据B树性质5:

  • 每个节点最多 个关键字,所以 ,即
  • 非根节点至少 个关键字,图中非根节点最少有2个关键字,所以 ,即

因此合法的 值为

18.1-3 当t=2时,画出包含关键字{1,2,3,4,5}的所有合法B树

时,每个节点最多 个关键字,最少 个关键字(根至少1个)。

所有合法B树结构如下(仅列出根节点的不同情况):

情况1:根节点含3个关键字(满节点)

  • 根:[1, 2, 3],左孩子:[4],右孩子:[5]
  • 根:[1, 2, 4],左孩子:[3],右孩子:[5]
  • 根:[1, 3, 4],左孩子:[2],右孩子:[5]
  • …(多种排列)

情况2:根节点含2个关键字

  • 根:[2, 4],左孩子:[1],中孩子:[3],右孩子:[5]
  • 根:[3, 5],左孩子:[1],中孩子:[2],右孩子:[4]
  • …(多种排列)

情况3:根节点含1个关键字,高度为2

  • 根:[3],左孩子含[1,2],右孩子含[4,5]
  • 根:[3],左孩子含[1],中孩子含[2],右孩子含[4,5]
  • …(多种排列)

情况4:所有关键字在一个节点中

  • 根:[1, 2, 3, 4, 5]——但 时最多3个关键字,不合法!

因此不存在所有关键字在一个节点中的情况。合法B树的高度为1或2。

18.1-4 证明:高度为h的B树中,关键字数n满足

证明

用数学归纳法。设 为高度为 的B树中最多关键字数。

【基例: 基例(只有根节点)。根最多 个关键字。

【归纳步:根最多 个关键字 + 棵子树各 个】 归纳步:假设

高度为 的B树,根最多 个关键字,最多 棵子树,每棵子树高度最多

18.1-5 将红黑树中的红色节点吸收到其黑色父节点中,说明得到的树是一棵B树

分析

红黑树满足以下性质:

  1. 每个节点是红色或黑色
  2. 根节点是黑色
  3. 每个叶节点(NIL)是黑色
  4. 红色节点的两个子节点都是黑色(不能有连续红色节点)
  5. 从任一节点到其后代叶节点的所有路径包含相同数目的黑色节点

将每个红色节点与其黑色父节点合并后:

  • 合并后的”超级节点”可以包含1个、2个或3个关键字(对应原黑节点+0/1/2个红色子节点)
  • 这恰好对应 的B树(2-3-4树),其中每个节点可以有1~3个关键字
  • 红黑树的黑高度对应B树的高度
  • 红黑树性质5(黑高相同)保证所有叶节点在同一层(B树性质4)
  • 红黑树性质4(无连续红色)保证合并后节点最多3个关键字(B树性质5,

视频学习指南

资源讲者/来源内容时长推荐度
MIT 6.006 Lecture 10Erik DemaineB树基本概念、高度分析、搜索操作~80min★★★★★
MIT 6.854 Lecture 5Erik DemaineB树高级变体、缓存无关B树~80min★★★★☆
Stanford CS166 (Advanced Data Structures)Keith SchwarzB树与B+树深入分析~60min★★★★★
Karpathy - “Let’s build GPT: from scratch” (类比)Andrej Karpathy虽然是神经网络教程,但其中对数据结构的讨论有启发~2h★★★☆☆
Abdul Bari - B TreesAbdul Bari (YouTube)B树可视化讲解,适合入门~20min★★★★☆

教材原文

算法导论(第4版)第18章 18.1节

正如我们在第14章中所看到的,平衡二叉搜索树(如红黑树)能保证各种基本动态集合操作在 的时间内完成。因为结点存储在磁盘上时,与内存访问相比,磁盘访问的代价要大好几个数量级,所以我们要寻找能减少磁盘I/O操作次数的搜索树结构。B树就是为此目的而设计的一种平衡搜索树。

B树的定义

一棵B树 是满足以下性质的有根树:

  1. 每个结点 具有以下属性:

    • :当前存储在结点 中的关键字个数,
    • 个关键字 以升序排列,
    • :一个布尔值,如果 是叶结点,则为 TRUE;如果 是内部结点,则为 FALSE。
  2. 每个内部结点 包含 个指向其孩子的指针 。叶结点没有孩子,所以它们的 属性无定义。

  3. 各关键字 对存储在各子树中的关键字范围加以分隔:如果 是任意子树 中的一个关键字,那么

  4. 每个叶结点具有相同的深度,即树的高度

  5. 结点关键字数量的约束:

    • 每个结点(根结点除外)必须至少有 个关键字。因此,除了根结点外,每个内部结点至少有 个孩子。如果树非空,根结点至少有一个关键字。
    • 每个结点可包含至多 个关键字。因此,一个内部结点至多可有 个孩子。当一个结点恰好有 个关键字时,称该结点是满的(full)。

B树中关键字的数量与树的高度之间的关系如下。如果 ,那么对于高度为 、最小度为 的B树,有:


参见Wiki

第18章-B树 B树的定义