B树和B+树是用于动态多路平衡查找的树形数据结构,主要用于磁盘存储与数据库索引中。它们的设计目标是减少磁盘 I/O 操作,提高大规模数据的查找、插入和删除效率。
以下从定义、性质、操作原理、实现、应用场景、优缺点以及二者的对比等方面详细介绍 B 树和 B+ 树。
1. B树 (B-Tree)
(1) B树的定义
B树是一种 自平衡的多路搜索树,它将数据存储在磁盘块中,允许每个节点有多个子节点(比二叉树更宽),并保持平衡。
- B树的阶数(Order)
m
定义了每个节点的最大子节点数:
- 每个节点最多有
m
个子节点。- 每个节点至少有
⌈m/2⌉
个子节点(根节点除外)。- 每个非叶子节点包含
k
个键值和k+1
个子节点(⌈m/2⌉ - 1 ≤ k ≤ m - 1
)。- 所有叶子节点处于同一层,保证树的平衡性。
(2) B树的性质
- 节点存储范围:
- 一个节点存储多个键值,键值按递增顺序排列。
- 平衡性:
- B树始终保持平衡,每个节点到叶子节点的路径长度相同。
- 动态性:
- B树能动态调整高度,保证效率。
- 多路分支:
- 一个节点可以有多个子节点,从而减少树的高度。
(3) B树的操作
查找
- 从根节点开始,在节点内使用二分查找定位键值。
- 如果键值不在当前节点,则根据键值范围递归进入对应的子节点。
- 时间复杂度:O(logn)O(\log n)O(logn)。
插入
- 在找到合适的叶子节点后插入键值。
- 如果插入导致节点超出阶数限制,则发生分裂:
- 将节点分裂为两部分,并将中间键提升到父节点。
- 若父节点也超出限制,则继续分裂,直到根节点。
- 分裂可能导致树的高度增加。
删除
- 删除的情况较为复杂:
- 若删除的键在叶子节点中,直接删除。
- 若删除的键在内部节点,则用前驱键或后继键替代,并递归删除。
- 若删除导致节点低于最小键数,则发生合并或借用:
- 合并:将相邻节点合并为一个节点。
- 借用:从相邻的兄弟节点借一个键值。
2. B+树 (B+ Tree)
(1) B+树的定义
B+树是 B树的一种变体,常用于数据库索引和文件系统中。
- 它在 B 树的基础上增加了以下特点:
- 所有的键值都存储在叶子节点。
- 非叶子节点只存储用于索引的键值,不存储数据。
- 所有叶子节点通过指针相连,形成一个链表。
(2) B+树的性质
- 平衡性:
- 和 B 树一样,B+ 树是平衡的,所有叶子节点处于同一层。
- 更高的分支因子:
- 由于非叶子节点不存储数据,单个节点能容纳更多键值,导致树的高度更低。
- 范围查询高效:
- 因为叶子节点通过链表连接,B+ 树在范围查询时可以直接遍历链表。
(3) B+树的操作
查找
- 和 B 树类似,在非叶子节点中通过二分查找键值范围,最终定位到叶子节点。
- 数据总是在叶子节点中存储。
- 时间复杂度:O(logn)O(\log n)O(logn)。
插入
- 在叶子节点中插入键值。
- 如果节点超出阶数限制,发生分裂:
- 中间键值提升到父节点,但数据只保留在叶子节点。
- 分裂过程和 B 树类似,但分裂仅限于叶子节点。
删除
- 删除键值时,仅影响叶子节点。
- 若节点低于最小键数,则发生合并或借用:
- 和 B 树类似,但仅在叶子节点上执行合并或借用。
3. B树与B+树的对比
特性 B树 B+树 键值存储 所有节点都存储键值,内部节点也存储数据。 所有数据存储在叶子节点,非叶子节点仅存索引。 查询效率 每次查找可能需要到达叶子节点才能找到数据。 所有数据在叶子节点,查询效率稍高。 范围查询 范围查询效率较低,需要在树中遍历多个节点。 范围查询效率高,可通过叶子节点链表直接遍历。 树的高度 相对较高,因为非叶子节点存储数据。 相对较低,单个节点容纳更多索引键值。 空间利用率 较低,因为内部节点也存储数据,空间分布不均。 较高,非叶子节点仅存索引,数据更集中。 适用场景 适用于内存中数据结构,数据量较小时使用。 适用于文件系统、数据库等大规模存储场景。
4. B树与B+树的应用场景
(1) B树的应用
- B 树主要用于内存中的动态数据结构,例如:
- 操作系统中的多级页表。
- 小规模的索引场景。
(2) B+树的应用
- B+ 树由于支持高效的范围查询和更高的空间利用率,广泛用于:
- 数据库索引:
- 如 MySQL 的 InnoDB 使用 B+ 树作为索引实现。
- 文件系统:
- 如 NTFS 和 Ext 文件系统使用 B+ 树管理文件目录。
- 磁盘存储:
- 高效组织和检索磁盘块中的数据。
5. B树与B+树的优缺点
(1) B树的优缺点
- 优点:
- 插入、删除效率高,操作简单。
- 不需要额外的链表,数据集中在树结构中。
- 缺点:
- 范围查询效率较低。
- 非叶子节点存储数据,导致空间利用率较低。
(2) B+树的优缺点
- 优点:
- 查询效率高,特别是范围查询。
- 空间利用率高,树的高度较低。
- 叶子节点链表提供更好的数据遍历能力。
- 缺点:
- 实现稍复杂。
- 插入和删除时需要更多的指针操作。
6. 总结
特点 B树 B+树 结构 数据分布在所有节点中 数据集中在叶子节点,非叶子节点只存索引 查询性能 查询效率适中 查询效率更高 范围查询性能 较差,需要逐层遍历节点 高效,直接通过叶子节点链表遍历 实现复杂性 较简单 较复杂 适用场景 小规模数据索引 大规模存储系统,如数据库、文件系统 总的来说,B+树更适合大规模数据的存储和查询,而 B 树适合内存中的动态操作。两者在实际应用中各有侧重。