news 2026/5/1 4:08:39

B_树(B-Tree)是一种自平衡的多路搜索树,广泛用于数据库和文件系统中以高效管理大量数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
B_树(B-Tree)是一种自平衡的多路搜索树,广泛用于数据库和文件系统中以高效管理大量数据

B_树(B-Tree)是一种自平衡的多路搜索树,广泛用于数据库和文件系统中以高效管理大量数据。以下是关于 m 阶 B_树的完整定义与相关特性:

1. m 阶 B_树的定义

一个 m 阶 B_树满足以下性质:

  • 每个节点最多有 m 个子树;
  • 根节点(若非叶子)至少有 2 个子树;
  • 所有非根且非叶节点至少有 ⌈m/2⌉ 个子树;
  • 每个非叶节点的结构为:(n, A₀, K₁, A₁, K₂, A₂, …, Kₙ, Aₙ),其中:
    • n 是该节点中关键字的个数;
    • K₁ < K₂ < … < Kₙ 是关键字;
    • A₀ 是指向关键字小于 K₁ 的子树的指针;
    • Aᵢ 是指向关键字介于 Kᵢ 和 Kᵢ₊₁ 之间的子树的指针(i = 1 到 n−1);
    • Aₙ 是指向关键字大于 Kₙ 的子树的指针;
  • 关键字个数 n 满足:⌈m/2⌉ − 1 ≤ n ≤ m − 1;
  • 所有叶节点位于同一层,表示查找失败的位置(外部节点),不存储实际数据。

示例:对于 4 阶 B_树,每个节点最多有 4 棵子树,最少(非根)有 ⌈4/2⌉ = 2 棵子树;关键字个数范围是 1 到 3。

2. 查找过程

B_树的查找从根节点开始,按如下步骤进行:

  1. 在当前节点的关键字序列中使用二分查找目标值;
  2. 若找到,则查找成功;
  3. 若未找到,则根据关键字区间确定下一子树指针;
  4. 递归或迭代进入对应子树继续查找;
  5. 直到在某节点中找到目标,或到达空指针(即叶节点层)时失败退出。

由于 B_树是平衡树,所有叶节点在同一层,因此最坏情况下的查找路径长度为 O(logₘ N),其中 N 是关键字总数,具有良好的时间性能。

3. 应用场景

B_树主要用于磁盘等外部存储系统的索引结构,原因包括:

  • 多路分支减少树的高度,降低 I/O 次数;
  • 平衡性保证操作效率稳定;
  • 支持高效的插入、删除和查找操作;
  • 常见变体如 B+ 树在数据库(如 MySQL 的 InnoDB 引擎)中广泛应用。
# 简化的 B_树节点类示例(Python)classBTreeNode:def__init__(self,m,is_leaf=False):self.max_children=m self.min_keys=(m+1)//2-1# ⌈m/2⌉ - 1self.is_leaf=is_leaf self.keys=[]# 存储关键字self.children=[]# 存储子节点指针defis_full(self):returnlen(self.keys)>=self.max_children-1

实现 B_树的插入操作需要遵循其结构特性,确保在插入新关键字后仍保持平衡。当节点的关键字数超过上限(m−1)时,必须进行节点分裂以维持 B_树的性质。


✅ B_树插入操作的基本步骤(m 阶)

  1. 从根节点开始查找插入位置

    • 若树为空,则创建新的根节点,插入关键字;
    • 否则,递归向下查找应插入的叶节点。
  2. 找到合适的叶节点进行插入

    • 插入操作总是在叶节点中进行(类似二叉搜索树);
    • 在目标叶节点中按顺序插入关键字。
  3. 检查是否违反最大关键字限制

    • 如果该节点的关键字个数 ≤ m−1:完成插入;
    • 如果 > m−1(即满了),则对该节点进行分裂处理
  4. 节点分裂(Split)过程
    假设一个节点有 m 个关键字(已满),需分裂为两个节点:

    • 取中间关键字K[⌈m/2⌉]作为提升关键字(升到父节点);
    • 左子节点包含前 ⌈m/2⌉−1 个关键字;
    • 右子节点包含后 ⌊m/2⌋ 个关键字;
    • 原节点保留左半部分,新建右半部分节点;
    • 将中间关键字插入父节点,并添加指向新节点的指针;
    • 若父节点也满,则继续向上分裂,必要时创建新根。
  5. 更新父节点或创建新根

    • 如果分裂传播到根节点,且根已满,则将根分裂,并新建一个根节点(树高+1)。

🔧 示例:4 阶 B_树插入与分裂

  • m = 4 → 每个节点最多 3 个关键字,最多 4 棵子树;
  • 最少关键字数:⌈4/2⌉ − 1 = 1;
  • 当某节点有 4 个关键字时(超出 m−1=3),必须分裂。
分裂示例:

当前节点关键字为[10, 20, 30, 40](已满)

[10, 20, 30, 40]

→ 中间位置是第 ⌈4/2⌉ = 2 个关键字 → 升级K₂ = 20到父节点
→ 左节点保留[10]
→ 右节点为[30, 40]
→ 原节点变为[20]并拆分为两孩子:

[20] / \ [10] [30, 40]

如果原节点是根节点,则此时生成新的根节点[20],树高度加一。


💡 Python 简化代码框架(示意)

classBTreeNode:def__init__(self,m,is_leaf=True):self.m=m self.is_leaf=is_leaf self.keys=[]self.children=[]defis_full(self):returnlen(self.keys)>=self.m-1defsplit_child(parent,index):m=parent.m full_node=parent.children[index]mid=m//2# 分裂点索引(对于 m=4,mid=2)median_key=full_node.keys[mid]# 创建新节点(右半部分)new_node=BTreeNode(m,is_leaf=full_node.is_leaf)new_node.keys=full_node.keys[mid+1:]ifnotfull_node.is_leaf:new_node.children=full_node.children[mid+1:]# 修改原节点为左半部分left_keys=full_node.keys[:mid]ifnotfull_node.is_leaf:left_children=full_node.children[:mid+1]else:left_children=[]# 提取中间关键字并插入父节点parent.keys.insert(index,median_key)parent.children[index]=BTreeNode(m,is_leaf=full_node.is_leaf)parent.children[index].keys=left_keys parent.children[index].children=left_children parent.children.insert(index+1,new_node)definsert_non_full(node,key):i=len(node.keys)-1ifnode.is_leaf:# 直接插入并排序node.keys.append(None)whilei>=0andkey<node.keys[i]:node.keys[i+1]=node.keys[i]i-=1node.keys[i+1]=keyelse:# 找到子树位置whilei>=0andkey<node.keys[i]:i-=1i+=1child=node.children[i]ifchild.is_full():split_child(node,i)ifkey>node.keys[i]:i+=1insert_non_full(node.children[i],key)defbtree_insert(root,key):ifroot.is_full():# 根节点已满,创建新根m=root.m new_root=BTreeNode(m,False)new_root.children.append(root)split_child(new_root,0)insert_non_full(new_root,key)returnnew_rootelse:insert_non_full(root,key)returnroot

⚠️ 注意事项

  • 插入总是发生在叶节点;
  • 分裂可能自底向上传播;
  • 树始终保持平衡,所有叶节点在同一层;
  • 时间复杂度:O(logₘ N),每次操作涉及 O(h) 次磁盘访问(h 为树高)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 7:18:14

迅雷离线下载后自动OCR?HunyuanOCR在下载工具中的创新应用

HunyuanOCR在下载工具中的创新应用 在今天的数字生活中&#xff0c;我们每天都在下载各种文件&#xff1a;从学术论文、电子书到网页截图、扫描文档。但你有没有遇到过这样的情况&#xff1f;好不容易用迅雷离线下载了一堆PDF讲义或图片资料&#xff0c;结果打开一看全是图像格…

作者头像 李华
网站建设 2026/5/1 9:25:33

如何将HunyuanOCR嵌入Web应用实现在线OCR工具网站

如何将HunyuanOCR嵌入Web应用实现在线OCR工具网站 在数字化浪潮席卷各行各业的今天&#xff0c;文档信息的快速提取与跨语言理解已成为办公、教育和跨境业务中的刚需。一张发票、一份合同、一段视频字幕——这些原本“沉睡”在图像中的文字&#xff0c;正通过光学字符识别&…

作者头像 李华
网站建设 2026/5/1 8:35:05

C++26来了!揭秘std::future新增超时控制的底层实现原理

第一章&#xff1a;C26 std::future 超时机制概述C26 对并发编程模型进行了重要增强&#xff0c;其中 std::future 的超时机制得到了标准化和统一。此前版本的 C&#xff08;如 C11 至 C23&#xff09;虽然支持通过 wait_for 和 wait_until 实现有限等待&#xff0c;但行为在异…

作者头像 李华
网站建设 2026/4/19 20:41:28

Clang 17性能优化十大陷阱:90%工程师都踩过的坑,你中了几个?

第一章&#xff1a;Clang 17性能优化的核心价值与挑战Clang 17作为LLVM项目的重要组成部分&#xff0c;不仅延续了对C、C和Objective-C语言的高效支持&#xff0c;更在编译时性能、代码生成质量以及诊断信息精确性方面实现了显著提升。其核心价值体现在更智能的优化策略、更低的…

作者头像 李华
网站建设 2026/5/1 8:36:54

百度网盘智能分类:结合HunyuanOCR识别图片内容打标签

百度网盘智能分类&#xff1a;结合HunyuanOCR识别图片内容打标签 在百度网盘每天处理数亿张用户上传的图片时&#xff0c;一个看似简单却长期困扰工程师的问题浮现出来&#xff1a;如何让一张名为“IMG_20240512_193845.jpg”的合同截图&#xff0c;能被搜索“租房合同”准确命…

作者头像 李华