B 树,B+树,这个坑留了三个月了,今天来补上,参考视频链接:B树自在人心,看不懂,我当场把这个树吃掉!
重要资料,动态演示页面:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
B树
下面我来逻辑一下我的整理
定义
一棵m阶的B树,满足下列特性的m叉树:
-
树中每个结点至多有m棵子树,即关键字至多m-1个;
-
若根结点不是叶子结点,则至少有两棵子树,即关键字可以是1个;
-
除根之外的所有非终端结点至少有
[m/2](向上取整)
棵子树; -
所有的非终端结点中包含下列信息数据
其中m为阶树;
Ki(i=1,…,m-1)为关键字,且Ki<Ki+1,即终端结点内关键字有序;
Pi(i=1,…,m)为指向子树根结点的指针,且指针Pi所指子树中所有结点的关键字均小于Ki,Pi+1所指子树中所有结点的关键字均大于Ki -
所有叶结点处于同一层;可以用空指针表示,是查找失败到达的位置。
举例说明一下5阶B树
- 性质1,,每个终端结点都至多可以填充4个关键字(对应K),5棵子树(对应P)
- 性质2,根节点可以只有1个关键字,2棵子树
- 性质3,除根之外的所有非终端结点,至少3棵树,至少2个关键字
- 性质4,终端结点内关键字有序,对应K,如(15,26)、(22,25);P1所指子树中所有结点的关键字均小于K1,P2所指子树中所有结点的关键字均大于K1,依次类推
- 性质5,所有叶结点处于同一层,最终高度都为3
B树插入过程
用以下关键字序列{1,2,6,7,11,4,8,13,10,5,17,9,16,20,3,12,14,18,19,15}创建一棵5阶B树。
由性质我们可以得知,非终端结点关键字最多4个
初始情况
1,2,6,7插入
11插入
调整,取出中间关键字6
4,8,13插入
10插入
调整,取出中间关键字10
5,17,9,16插入
20插入
调整,取出中间关键字16
3插入
调整,取出中间关键字3
12,14,18,19插入
15插入
调整,取出中间关键字13
调整,取出中间关键字10
B树删除过程
对于上述构建的B树,给出删除关键字8、16、15、4的过程。
8删除
由性质3可得,除根之外的所有非终端结点至少有[m/2](向上取整)
棵子树,即至少3棵树,至少2个关键字,删除8后不影响B树性质,直接删除
16删除
由性质3可得,除根之外的所有非终端结点至少有[m/2](向上取整)
棵子树,即至少3棵树,至少2个关键字,删除16后影响B树性质,不能直接删除,需要调整
这里调整一般有两种思路
- 向孩子结点借结点
- 向兄弟结点借结点
图中使用了第2种策略,借
调整后
PS:插入第一种策略
15删除
15删除与上述第一种策略一致,借兄弟,调整后
4删除
最后一种出现无兄弟,无孩子可借,必须合并结点
合并思路,将删除后的非终端结点与兄弟非终端结点合并(原则是选择关键字较少的兄弟结点),同时合并父结点一个关键字,这里假设与右兄弟合并
合并后如下
此时关键字也是相同的情况,需要再做一次合并
合并后
B+树
B+树是基于B树的变形时,一棵m阶的B+树和m阶的B一树的差异在于:
- 在B+树中,具有n个关键字的结点含有n个分支;而在B树中,具有n个关键字的结点含有n+1个分支。
- 在B+树中,每个结点(除根结点以外)中的关键字个数n的取值范围为[m/2]<=n<=m,根结点的取值范围为2<=n<=m;而在B树中,它们的取值范围分别是[m/2]-1<=n<=m和1<=n<=m(B+树关键字同分支相同)
- 在B+树中叶子结点包含信息,并且包含了全部关键字,叶子结点引出的指针指向记录。
- B+树中所有非叶子结点仅仅起到一个索引的作用,即结点中的每个索引项只含有对应子树的最大关键字和指向该子树的指针,不含有该关键字对应记录的存储地址;而在B树中,每个关键字对应一个记录的存槠地址
- 在B+树上有一个指针指向关键字最小的叶子结点,所有叶子结点链接成一个线性链表,而B树没有。