用object[]模拟b+树叶子节点时,设阶数m=4,数组长为4,插入超5个则拆分为左2右3,并取右半最小key上推;非叶节点存(key,指针),超限按中间key拆分;需维护prevleafidx/nextleafidx链表链接。

用数组模拟 B+ 树叶子节点拆分
在 Java 中不依赖复杂结构体时,可用固定长度的 Object[] 模拟叶子节点。假设阶数 m=4(即最多存 4 个键值对),则叶子节点数组长度设为 4,每个元素为 Map.Entry
- 将原数组前 ⌊m/2⌋=2 个元素保留在原节点(左半)
- 后 ⌈m/2⌉=3 个元素移入新节点(右半)
- 取右半部分的最小 key 作为“上推索引项”,供父节点插入
数组模拟非叶子节点的索引聚合
非叶子节点不存 value,只存 (key, childPointer) 对,其中 childPointer 可用整型索引(如指向叶子节点数组的下标)或对象引用。仍用 Object[] 存储,每个元素是 IndexEntry
- 按 key 排序后,取中间 key(如第 ⌈(size−1)/2⌉ 个)分离为上层索引
- 左侧索引(含小于中间 key 的所有项)保留在原节点
- 右侧索引(大于等于中间 key 的项)放入新节点
- 将中间 key 和两个子节点指针组成新索引项,递归向上插入父节点
维护叶子链表与父节点同步
B+ 树要求所有叶子节点通过指针构成有序链表。用数组模拟时,可在每个叶子节点对象中加两个 int 字段:prevLeafIdx 和 nextLeafIdx,指向叶子节点池(如 List
- 原节点的 nextLeafIdx 改为新节点索引
- 新节点的 prevLeafIdx 设为原节点索引
- 原节点原 nextLeafIdx 对应节点的 prevLeafIdx 改为新节点索引
同时,父节点中对应原 childPointer 的位置需替换为两个新子节点指针,并插入上推 key。
关键细节与避坑提示
纯数组实现易忽略边界逻辑:
- 排序必须稳定,避免相同 key 插入顺序错乱;建议用 Arrays.sort(arr, Comparator.comparing(e -> e.getKey()))
- 拆分时注意深拷贝:若数组存的是引用类型,直接赋值会导致多节点共享同一对象,应新建 Entry 实例
- 根节点特殊处理:根拆分后高度+1,需新建根节点,其仅含一个索引项(上推 key + 两个子节点)
- 删除暂不触发合并可简化实现,但若支持删除,需检查兄弟节点容量并执行借位或合并
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











