一、B-树的定义
B-树是一种特殊的平衡m叉排序树,要求所有叶节点在同一层。B-树中所有结点孩子结点个数的最大值称为 B-树 的阶,通常用 m 表示,从查找效率考虑,要求 m>=3
一颗 m 阶的 B- 树,或为空树,或为满足下列特性的m叉树:
- 树中每个结点至多有m棵子树;
- 如果根结点不是叶子结点,则至少有 2 棵子树,对应 1 个关键字;
- 除了根之外的所有非终端结点至少有 ⌈m/2⌉ 棵子树,对应 ⌈m/2⌉-1 个关键字;
- 有 n 个子树的结点有 n-1 个关键字,按 递增顺序 排序
- 叶结点处于同一层;可以用空指针表示,是查找失败到达的位置。
- 每个结点的结构为
n | … | |||
---|---|---|---|---|
… |
其中,
- n 为该结点中关键字的个数
- 为该结点的关键字且满足
- 为该结点的孩子结点指针且满足 所指结点上的关键字大于 且小于 , 所指结点小于 , 所指结点大于
示例介绍
- 由橙色方框中的内容可知,该结点具有3个关键字和4个分支(子树),因为该分支是B-树的最大分支,所以这是一棵4阶B-树
- 如图所示为一棵4阶B-树,因此⌈m/2⌉=⌈4/2⌉=2,因此,除了根节点外,所有的结点至少有2个分支,对应1个关键字
- B-树的叶子结点均在第三层,代表查找不成功的位置
- 下层结点内的关键字取值总是落在由上层结点关键字所划分的区间内,由绿色方框中的内容可知,该结点划分为三个区间:(-∞,43)(43,78)(78,+∞)
- 该B-树的高度为3(不包括叶子结点层),总结点数为20
二、B-树查找关键字
由于B-树是一种特殊的平衡m叉排序树,二叉排序树是二路查找,B-树是多路查找。因为B-树结点内的关键字是有序的,在结点内进行查找时除了顺序查找之外,还可以用折半查找来提高效率。B-树的具体查找步骤如下(key为要查找的关键字)
- 先让key与根结点中的关键字比较,如果key等于k[i],则查找成功
- 若key<k[1],则到p[0]所指示的子树中进行继续查找
- 若key>k[n],则到p[n]所指示的子树中进行继续查找
- 若k[i]<key<k[i+1],则到p[i]所指示的子树中进行继续查找
- 如果最后遇到空指针,则证明查找不成功
三、B-树插入关键字
首先,我们应该明确,根结点若存在,那么根结点的关键字的个数为1<=n<=m-1;叶子结点的关键字的个数为 ⌈m/2⌉-1<=n<=m-1。因此,若插入关键字使得结点不满足条件,则应当作相应的调整。插入操作只会使得B-树逐渐变高而不会改变叶子结点在同一层的特性。 B-树的具体插入步骤如下(key为要查找的关键字)
- 根据关键字key,在排序树T上查找,并在失败处插入之。(插入位置一定出现在终端结点上)
- 插入后检查被插入结点内关键字的个数,如果关键字个数大于 m-1,则需要进行拆分,其拆分步骤如下:
- 结点内的关键字若已经有m个
- 取出第⌈m/2⌉个关键字
- 将第1~⌈m/2⌉-1个关键字和第⌈m/2⌉+1~m个关键字做成两个结点连接在第⌈m/2⌉个关键字左右的指针中
- 将第⌈m/2⌉个关键字插入其父结点的相应位置
- 如果父结点内又出现了关键字个数超出规定范围的情况,则继续进行拆分操作
四、B-树的创建
根据插入算法,逐个插入关键字key
五、B-树删除关键字
同样,根结点若存在,那么根结点的关键字的个数为1<=n<=m-1;叶子结点的关键字的个数为 ⌈m/2⌉-1<=n<=m-1。因此,若删除关键字使得结点不满足条件,则应当作相应的调整。
- 如果要删除的关键字在终端结点上,这时有以下3种情况
- 结点内的关键字个数大于 ⌈m/2⌉-1,这时可以直接删除
- 结点内的关键字个数等于 ⌈m/2⌉-1,并且其左右兄弟结点中存在关键字个数大于 ⌈m/2⌉-1,则从关键字个数大于 ⌈m/2⌉-1的兄弟结点借关键字
- 结点内的关键字个数等于 ⌈m/2⌉-1,并且其左右兄弟结点中存在关键字个数等于 ⌈m/2⌉-1,则需要对结点进行合并
- 如果要删除的关键字不在终端结点上,则先用其相邻关键字结点取代它,然后将原问题转换为“删除相邻关键字结点”(相邻关键字:原关键字为其左子树中值最大的关键字或者其右子树中值最小的关键字)
六、B-树和B+树的比较
(1)B-树
(2)B+树
- 在B+树中,n个分支对应n个关键字;在B-树中,n个分支对应n-1个关键字
- 在B+树中,所有的非叶子结点仅起到一个索引的作用,即结点中的每个索引项只含有对应子树的最大关键字和指向该子树的指针,不包含该关键字对应记录的存储地址;在B-树中,每个关键字对应一个记录的存储地址
- 在B+树中,叶子结点包含了全部关键字,叶子结点引出的指针指向记录;在B-树中,叶子结点和非叶子结点的作用相同。
- 在B+树中,每个结点的结构为
… | ||||
---|---|---|---|---|
… |
其中,
- 为该结点的关键字且满足
- 为该结点的孩子结点指针且满足 所指结点上的关键字大于 且小于等于 (必包含 ), 所指结点小于等于 (必包含 )