1.B树即B-Tree
(图转载)
B树是一种多叉平衡查找树,红黑树是一种二叉平衡查找树,B树的多叉结构使得对于元素数量非常多的情况,树的深度不会像二叉树那么深,保证查询效率。
B-Tree是为了磁盘或其他存储设备设计的一种多叉平衡查找树,相比红黑树在降低磁盘I/O方面做得更好, 许多数据库都是用B-Tree 和 B*Tree, B+Tree来存储信息。
性质:m阶的B树
①树中每个节点最多含有m个孩子
②除根节点和叶子节点,其他每个节点至少含有[m/2](向上取整)个子节点
③根节点至少还有2个孩子
④叶子节点不包括任何关键字信息。
⑤每个非终端节点包含n个关键字信息
1)安关键字升序进行排序
2)节点的关键字的个数n满足:[m/2-1]<=n<=m-1
树中每个节点至少含有[m/2]个节点,最多含有m个节点
B树的插入
①叶子节点空间足够,即关键字个数小于m-1,直接插入
②若空间满,需要进行分裂,中间关键字元素上移到父节点,左侧右侧分别分裂形成新的节点。
B树的删除
进行元素的查找,若元素存在,则删除。删除元素后,判断该元素是否有左右孩子节点。
若有,上移孩子节点中的相近元素(左孩子中最右边或者右孩子中最左边),移动后情况
若没有,直接删除,移动后情况
删除元素,然后进行元素的移动,如果节点关键字数据不满足条件(<[m/2]-1),则需要看齐相邻的兄弟节点是否丰满(>=[m/2]-1)
若丰满,向父节点借一个元素来满足
若其相邻兄弟节点刚脱贫,即借了之后其节点数目<[m/2]-1,则该节点与其相连的某一兄弟节点进行合并成一个节点
2.B+Tree
B树的一种变形,m阶B树和B+树的区别:
①所有叶子节点包含全部的关键字信息,以及指向这些关键字的指针,叶子节点中关键字进行有序连接。
②非叶节点相当于叶子节点的索引(稀疏索引),叶子节点是存储数据的数据层。
(图转载)
B+树比B-树更加适合操作系统的文件索引和数据索引
(B树内部节点存放关键字和指针,B+树内部节点只存放关键字索引,叶节点存放关键字和指针)
①磁盘读写代价更低,B+树的内部节点没有指向关键字具体信息的指针,内部节点相对于B树更小。如果把所有同一内部节点的关键字(索引)放在同一块磁盘中,盘块所能容纳的关键字数量也就越多,一次性读入内存中的需要查找的关键字也就越多,相对IO读写次数降低。
②B+树的查询效率更加稳定。
非叶节点是叶子节点中关键字的索引,所以任何关键字的查找都必须走根节点到叶子节点的路,查询路径长度相同,使得每个数据查询效率相当。
总结:B树提高了I/O性能但是并没有解决数据查询效率低下,B+树只要遍历叶子节点就能实现整棵树的遍历,支持基于范围的查询,而B树不支持(效率低)。
3.B*Tree
B*树是B+树的变体,在B+树的非根和非叶子节点增加指向兄弟的指针。
(图转载)
B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针。
B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针。
总结:
B树,多叉平衡搜索树,非叶节点存储值指向关键字范围的子节点;所有关键字在树中出现一次,非叶子节点可以命中。
B+树,在B树的基础上,为叶子节点增加索引,所有关键字都在叶子节点中出现,非叶节点作为叶子节点的索引;叶子节点命中
B*树,在B+树的基础上,为非叶节点也增加链表指针。