B-树
定义
B-树是一种平衡的 M(M>=2)路查找树,B-树也可以是空树,每个节点可以拥有多个子节点,从而有效减少树的高度,提高查找效率。
特性
- 根节点至少有两个孩子;
- 每个非根节点至少有 M/2-1(上取整) 个关键字,至多有 M-1 个关键字,并且以升序排列;
- 每个非根节点至少有 M/2(上取整) 个孩子,至多有 M 个孩子;
- key[i] 和 key[i+1] 之间的孩子节点的值介于 key[i]、key[i+1] 之间;
- B-树通过节点的分裂和合并操作来保持树的平衡,所有叶子节点都位于同一层。
B-树的插入分析
以 M=3 为例,每个节点中存储两个数据,两个数据可以将区间分割为三部分,即最多有两个关键字,三个孩子。 但是为了方便,对于每个节点,当插入第三个关键字时不分裂,在插入第三个关键字之后再分裂,可以想象成每个节点最多有三个关键字,最多有四个孩子。
下面以插入序列【53,139,75,49,145,36,101】为例构建 B 树:
- 插入 53
- 插入 139
- 插入 75
- 引发分裂
- 插入 49 和 145
- 插入 36
- 引发分裂
- 插入 101
- 引发分裂
- 再次引发分裂
B-树插入总结
- 如果树为空,直接插入新节点中,该节点为树的根节点
- 树非空,找待插入元素在树中的插入位置 (注意:找到的插入节点位置一定在叶子节点中)
- 检测是否找到插入位置 (假设树中的 key 唯一,即该元素已经存在时则不插入)
- 按照插入排序的思想将该元素插入到找到的节点中
- 检测该节点是否满足 B-树的性质:即该节点中的元素个数是否等于 M,如果小于则满足
- 如果插入后节点不满足 B 树的性质,需要对该节点进行分裂:
- 申请新节点
- 找到该节点的中间位置
- 将该节点中间位置右侧的元素以及其孩子搬移到新节点中
- 将中间位置元素以及新节点往该节点的双亲节点中插入,即继续步骤 4
- 如果向上已经分裂到根节点的位置,插入结束
模拟实现 B-树
基本结构
Pair.java
public class Pair <K,V>{
private K key;
private V val;
public Pair(K key, V val) {
this.key = key;
this.val = val;
}
public K getKey() { return key; }
public void setKey(K key) { this.key = key; }
V { val; }
{ .val = val; }
}


