# B-,B+,B*树
# B树
首先注意:B树就是B-树,"-"是个连字符号,不是减号。 B-树是一种平衡的多路查找(又称排序)树,在文件系统中有所应用。主要用作文件的索引。其中的B就表示平衡(Balance)
一棵m阶B树(balanced tree of order m
)是一棵平衡的m路搜索树。它或者是空树,或者是满足下列性质的树:
- 根结点至少有两个子女。
- 每个中间节点都包含
k-1
个元素和k
个孩子,其中m/2 <= k <= m
- 每一个叶子节点都包含
k-1
个元素,其中m/2 <= k <= m
- 所有的叶子结点都位于同一层。
- 每个节点中的元素从小到大排列,节点当中
k-1
个元素正好是k
个孩子包含的元素的值域分界线。
如:(M=3)
B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;
B-树的特性:
- 关键字集合分布在整颗树中;
- 任何一个关键字出现且只出现在一个结点中;
- 搜索有可能在非叶子结点结束;
- 其搜索性能等价于在关键字全集内做一次二分查找;
- 自动层次控制;
# B+树
B+树是应文件系统所需而出的一种B-树的变型树。一棵m阶的B+树和m阶的B-树的差异在于:
- 有n棵子树的结点中含有n个关键字,每个关键字不保存数据,只用来索引,所有数据都保存在叶子节点。
- 所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
- 所有的非终端结点可以看成是索引部分,结点中仅含其子树(根结点)中的最大(或最小)关键字。
通常在B+树上有两个头指针,一个指向根结点,一个指向关键字最小的叶子结点。
B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;
# B*
树
是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针;
# B*
树定义了非叶子结点关键字个数至少为(2/3)*M
,即块的最低使用率为2/3(代替B+树的1/2);
B+树的分裂:
- 当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;
- B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;
B*树的分裂:
- 当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);
- 如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针;
所以,B*树分配新结点的概率比B+树要低,空间使用率更高;
# 总结
B-树(或B树)是一种平衡的多路查找(又称排序)树,在文件系统中有所应用。主要用作文件的索引。其中的B就表示平衡(Balance)
B+
树的叶子节点链表结构相比于 B- 树,便于扫库和范围检索。B+
树支持range-query
(区间查询)非常方便,而B树不支持。这是数据库选用B+
树的最主要原因。B*
树 是B+树的变体,B*
树分配新结点的概率比B+
树要低,空间使用率更高;
参考资料: