【数据结构】图解B树、B+树

目录

1.B树

1.2 性质

1.3 图示 最简单3阶B树

1.4 操作

1.5 应用

2.B+树

2.1 性质

2.2 图示

2.3 应用


1.B树

1.2 性质

  • B树的阶m:孩子节点个数(叉)的最大值
  • 1.分支数(子树)
    • 根节点最少可以有两个分支[2,m]
    • 非根非叶子的分支个数为 [ ceil(m/2),m]
  • 2.key数
    • 节点上key数量是(分叉数-1)
    • 叶最多m-1个
  • 3.key有序,搜索树
    • 节点内有序,
    • 节点间 大于左子,小于右子

1.3 图示 最简单3阶B树

1.4 操作

  • 插入
    • 不满直接放入节点
    • 满了节点->分裂
    • 父节点叉数大于m->向上生长

1.5 应用

  • mongodb索引 所有节点都携带对应id对应数据行

2.B+树

2.1 性质

  • 所有数据均存储在叶子节点,其余节点仅存储key值
    • 节点间key关系不再是<、> 而是 <=、>=
  • 叶子包含所有key,叶子成一个链

2.2 图示

2.3 应用

 

  • 用在磁盘文件组织数据索引和数据库索引
  • Mysql索引
  • B+ 树,只有叶节点才携带数据

    为了使内节点在一个页内多存储key,使得树的m阶更大,这样树高就更低,由于外部存储每个节点需要磁盘寻址,每找到寻址一个节点就耗费

### B与B+数据结构差异 #### 结构上的区别 B是一种多路平衡查找,其特点是每个节点可以包含多个关键字和子指针。具体而言,在一棵m阶的B中,除了根节点以外,其他内部节点的关键字数目至少为⌈m/2⌉-1,至多为m-1;子指针的数量则比关键字数量多1[^5]。 相比之下,B+是对B的一种改进形式。在B+中,所有的数据记录都存储在叶子节点上,而非叶节点仅作为索引存在。此外,B+的叶子节点之间通过链表相互连接,这使得范围查询更加高效[^1]。 #### 关键特性对比 - **子数量与关键字的关系** 在B中,子的数量总是比关键字数量多1,而在B+中,子的数量正好等于关键字的数量[^4]。 - **数据存储位置** B允许将数据存储在非叶子节点中,这意味着检索路径可能会经过多次磁盘访问才能到达实际数据所在的位置。然而,在B+里,只有叶子节点才真正保存数据项,这种设计减少了不必要的I/O开销[^3]。 - **顺序遍历能力** 由于B+的叶子节点形成了有序链接列表,因此支持高效的区间扫描操作。这是因为在执行范围查询时可以直接沿着这些链条移动而不必重新定位父级节点。 --- ### 应用场景分析 #### B的应用场景 尽管B+更广泛应用于现代数据库系统中,但某些特定场合下仍可考虑采用标准版的B: - 当应用程序主要依赖于单条目精确匹配而不是批量或连续区域提取时; - 对于那些不需要频繁进行范围查询的小型嵌入式环境下的简单索引构建任务来说可能是足够的解决方案之一。 #### B+的优势及其典型用途 鉴于上述特点,特别是在涉及大规模数据集管理以及需要优化随机存取成本的同时兼顾良好序列化表现的情况下,比如关系型数据库管理系统(RDBMS),地理信息系统(GIS)等领域内的次序排列需求较高的项目,则倾向于选用B+来组织信息层次结构[^2]。 另外值得注意的是,因为大多数实际工作负载都会涉及到一定程度上的邻近性参考效应(即一段时间内所请求的对象往往集中在某个局部范围内), 所以利用好基于物理地址相邻性的预加载机制能够进一步放大由B+所带来的性能增益效果。 --- ```python class TreeNode: def __init__(self, is_leaf=False): self.keys = [] self.children = [] self.is_leaf = is_leaf def insert_b_tree(node, key): index = find_index_for_key(node.keys, key) if node.is_leaf: node.keys.insert(index, key) else: child_node = node.children[index] if len(child_node.keys) >= (node.max_keys): # Assuming max_keys defined elsewhere. split_child(node, index) if key > node.keys[index]: index += 1 insert_b_tree(node.children[index], key) def split_child(parent, i): new_node = TreeNode(is_leaf=parent.children[i].is_leaf) mid_point = parent.children[i].max_keys // 2 moved_keys = parent.children[i].keys[mid_point:] del parent.children[i].keys[mid_point:] if not parent.children[i].is_leaf: moved_children = parent.children[i].children[mid_point + 1:] del parent.children[i].children[mid_point + 1:] new_node.keys = moved_keys[:] if not parent.children[i].is_leaf: new_node.children = moved_children[:] median_key = parent.children[i].keys.pop(mid_point - 1) parent.keys.insert(i, median_key) parent.children.insert(i + 1, new_node) ``` 以上是一个简化版本用于演示目的的Python伪代码片段展示如何向基本类型的B/B+插入新元素的过程的一部分逻辑流程图解说明例子。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值