B+树、B*树

一、 B+树

B+树定义

一棵B+树满足下列条件:

(1) 每个分支结点至多有m棵子树。

(2) 除根结点外,其他每个分支结点至少有⌊(m+1)/2)⌋棵子树。

(3) 根结点至少有两棵子树,至多有m棵子树。

(4) 有n棵子树的结点有n个关键字。

(5) 所有叶子结点包含全部(数据文件中记录) 关键字及指向相应记录的指针(或存放数据文件分块后每块的最大关键字及指向该块的指针),而且叶子结点按关键字大小顺序链接(可以把每个叶子结点看成是一个基本索引块,它的指针不再指向另一级索引块,而是直接指向数据文件中的记录)。

(6) 所有分支结点(可看成是索引的索引)中仅包含它的各个子结点(即下级索引的索引块)中最大(或最小)关键字及指向子结点的指针。

B+树的查找

B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;因此,在B+树中,不管查找成功与否,每次都是经过了一条从根结点到叶子结点的路径.

B+树中结点的插入

B+树的插入是从叶子结点开始,当插入后结点的关键字个数大于m时要分裂成两个结点,它们所含键值个数分别为:u=大于(m+1)/2的最小整数,v=小于(m+1)/2的最大整数;同时要使得它们的双亲结点中包含有这两个结点的最大关键字和指向它们的指针.若双亲结点的关键字个数还大于m,应继续分裂,依次类推.

B+树中结点的删除

B+树删除也是从叶子结点开始,当叶子结点中最大关键字被删除时,分支结点中的值可以作为”分界关键字”存在.若因删除操作而使结点中关键字个数小于m/2 (m/2结果取上界,如5/2结果为3)时,则从兄弟结点中调剂关键字或和兄弟结点合并.

B+树的特性:

1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

2.不可能在非叶子结点命中;

3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;

4.更适合文件索引系统;

二、B*-tree

B*-tree是B+-tree的变体,在B+树非根和非叶子结点再增加指向兄弟的指针;B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代替B+树的1/2)。给出了一个简单实例,如下图所示:

B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针。

B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针。

所以,B*树分配新结点的概率比B+树要低,空间使用率更高;