B树
- 根节点至少包含两个孩子
- 树中每个节点最多含有m个孩子(m >= 2)
- 除根节点和叶节点外,其他每个节点至少有cell(m/2)个孩子
- 所有叶子节点都位于同一层
插入:
插入的时候,我们需要记住一个规则:判断当前结点key的个数是否小于等于m-1,如果满足,直接插入即可,如果不满足,按节点的中间的key将这个节点分为左右两部分,中间的节点放到父节点中即可。
删除:
删除叶子节点的元素,如果删除之后,节点数还是大于m/2,这种情况只要直接删除即可。
对于非叶子节点的删除,我们需要用后继key(元素)覆盖要删除的key,然后在后继key所在的子支中删除该后继key。
如果删除叶子节点,如果删除元素后元素个数少于(m/2),并且它的兄弟节点的元素大于(m/2),也就是说兄弟节点的元素比最少值m/2还多,将先将父节点的元素移到该节点,然后将兄弟节点的元素再移动到父节点。
首先,还是将先将父节点的元素移到该节点,然后,将当前节点及它的兄弟节点中的key合并,形成一个新的节点。
B+树
https://www.jianshu.com/p/71700a464e97
0.有k个子结点的结点必然有k个关键码(B树的关键码数:(m/2,m))。
1.非叶子节点仅用来索引,不保存关键字记录的指针,数据都保存在叶子节点中
2.非叶子节点的子树指针与关键字个数相同;非叶子节点的子树指针P[i],指向关键字值[K[i],K[i+1])的子树
3.所有叶子节点均有一个链指针指向下一个叶子节点,并按大小顺序链接
4.B+树
插入:
当节点元素数量大于m-1的时候,按中间元素分裂成左右两部分,中间元素分裂到父节点当做索引存储,但是,本身中间元素还是分裂右边这一部分的。
删除:
叶子节点有指针的存在,向兄弟节点借元素时,不需要通过父节点了,而是可以直接通过兄弟节移动即可(前提是兄弟节点的元素大于m/2),然后更新父节点的索引;如果兄弟节点的元素不大于m/2(兄弟节点也没有多余的元素),则将当前节点和兄弟节点合并,并且删除父节点中的key
B+树相比于B树的优点
1、B+树的层级更少:相较于B树B+每个非叶子节点存储的关键字数更多,树的层级更少所以查询数据更快;
2、B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定;
3、B+树天然具备排序功能:B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。
4、B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。