B树,B+树都是多路查找树。普遍用于数据库和文件系统。
背景
随着存储数据量的提高,采用二叉查找树会使得树的高度变得很大,查询效率降低。而B,B+树可以降低树的高度,减少IO次数。
定义
B树
m阶的B树,满足一下条件
- 根节点如果不是叶子节点,则至少有两颗树
- 叶子节点包含的元素[m/2,m];
- 中间节点子树的个数:[ceil(m/2),m]
- 所有的叶子节点在同一层。所有节点的平衡因子为0
- 每个节点的节点的元素从小到大排列
举个例子:5阶B树,根节点的元素数量: 1 <= k <= 4,非根节点元素数量:
2 <= k <= 4.
B树插入
插入的是一条记录,即(key,value)键值对。如果B树中已经存在插入的键key,则用新的value替换旧的value.如果不存在这个key,那么一定是在叶子节点插入。
插入规则:
- 查找插入位置,即找到对应的叶子节点并插入
- 判断当前节点key的数量是不是小于m-1,如果满足,说明没有破坏B树结构,插入完成,反之,进入下一步骤
- 以节点中间的key为中心,将节点分裂为左右两个部分,中间的key插入到父节点中,这个key的左子树就是分裂后的左半部分,右子树就是分裂后的右子树。(如果父亲节点因为插入元素个数大于m-1了,那么需要继续分裂)
下面以5阶B树中插入[18,70,50,40,22,24,26,30]为例。
[
B树的删除
删除相对于插入复杂些。非根非叶子节点的关键字最少Min为 ceil(m/2)-1 (ceil表示取上界。在非叶子节点上删除关键字k,转化为在叶子节点上删除关键字。如下图删除关键字13,转化为在左边找最大的关键字12,用12覆盖13,再在叶子节点中删除12
** 在叶子节点中删除,分为以下三种情况**
- 假设该节点的关键字个数大于 Min,那么可以直接删除
- 假设该节点的关键字个数等于Min,说明不满足B树的定义。
- 若可以向兄弟节点借:借的18需要经过父亲节点
- 如果不能向兄弟节点借:
示例:
- 若可以向兄弟节点借:借的18需要经过父亲节点
B+树
- 中间节点不储存数据,只存储索引,数据都存储在叶子节点上。
所有的分支节点(可以看做索引)中的最大关键字仅包含它的所有子节点中的最大关键字,以及指向子节点的指针。
B+树插入
规则:当节点元素大于m-1,就将按照中间元素的左右两边,将其分为左右两个部分,中间元素插入到父节点,
B+树删除
因为叶子节点存在指针,当向兄弟节点借的时候,不需要经过父节点,可以直接通过兄弟节点移动(兄弟节点元素大于m/2),然后更新父节点的索引值。如果兄弟节点的元素不大于m/2,就将当前节点和兄弟节点合并