[数据结构]B树及其基本操作、B+树的基本概念

前言:写B树这种博客可能有很多大佬比我写的好,甚至我下面的文章也有许多相似之处,我是参考了大佬们的博客写下我的通俗理解,为了更好的复习,有相似之处莫怪!!!如果你看得上我的理解,那是我的幸运,祝你们有所获!!!

一、B树

B树就是B-树,叫做B-tree,全称Balance-tree(平衡多路查找树),使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度,这个数据结构一般用于数据库的索引,综合效率较高。(平衡:左右分布均匀,多路:相对于二叉树而言,二叉树就是二路查找树,查找时只有两条路,而B树有多条路,父节点有多个子结点)
下面为了通俗一点,我就没按照数据库那种理解:一个记录应该包含关键字和对应数据,也就是关键字在数据库中代表键,对应数据代表这个键在硬盘上的逻辑地址。下面单纯只讲关键字

B树的定义:一棵m阶B-tree(m>=3),每个结点至多可以拥有m个子结点。其也可以为空树,也可以为满足以下特性的树:
1、若根结点不是叶子结点,则至少有两个孩子结点,至多为m个;(根结点至少包含一个关键字)
3、除根结点和叶子结点外,其他结点,至少有ceil(m/2)个孩子结点,至多m个,其包含的关键字数=孩子数-1;(ceil(x):返回大于或者等于x的最小整数,这是java中的Math库函数,ceil(5/2)=2.0,ceil(2.5)=3,x必须是double类型,在这里为了方便就设为分数
4、每个结点中的关键字都按照从小到大的顺序排序,每个关键字的左子树中的所有关键字都小于它,而右子树的所有关键字都大于它。
5、所有叶子结点都出现在同一层次上,ceil(m/2)-1 <= 结点包含的关键字数目 <= m - 1;

[数据结构]B树及其基本操作、B+树的基本概念_第1张图片

二、B树的基本操作

1、B树的查找操作

B树的查找和二叉排序树的查找类似,B树每个结点上是多关键字的有序表,首先把根结点取出,在根结点所包含的关键字中查找给定的关键字,使用顺序查找也可以使用折半查找。若找到,则查找成功,否则,从指针信息指向的子树中去查找,当到达叶子结点时,则说明树中没有对应的关键字,查找失败。

2、B树的插入操作

在B树上插入关键字,首先要经过一个树根结点到叶子的查找过程,查找出K的插入位置,然后再进行插入。关键字的插入不是在叶子结点上进行的,而是首先在最底层的某个非终端结点中添加一个关键字,若该结点的关键字个数不超过m-1,则插入完成;否则·,若该节点的关键字个数已达到m个,这与B树的定义不符,将引起结点的“分裂”。
分裂方法:
(1)将结点中的关键字分成三部分,使得前后两部分的关键字个数均大于等ceil(m/2)-1,而中间部分只有一个关键字。
(2)前后两部分分成为两个结点,而中间部分的关键字将插入到父结点中。
(3)若插入父结点后,父结点中关键字个数超过m-1,则父结点继续分裂,直到插入某个父结点,且其关键字个数小于m。

[数据结构]B树及其基本操作、B+树的基本概念_第2张图片
3、B树的删除操作

(1)如果当前要删除关键字的结点位于非叶子结点上,则用后继结点覆盖要删除的结点关键字,然后在后继所在的子支中删除该后继结点的关键字。
(2)如果后继结点的关键字个数>=ceil(m/2)-1,则结束删除操作。否则执行下一步
(3)如果兄弟结点关键字个数大于ceil(m/2)-1,则兄弟结点的一个关键字上移到父结点,父结点中的一个关键字下移到后继结点。删除操作结束。否则执行下一步
(4)将父结点中关键字下移与当前结点关键字及其兄弟结点中的关键字合并,形成一个新的结点。原父结点中的关键字的两个孩子指针就变成了一个孩子指针,指向这个新结点。然后当前结点你的指针指向父结点。

一颗4阶B树,非根结点关键字个数,至少ceil(m/2)-1=1,至多3个。(此图为了理解,所以设置4阶,根结点至少一个关键字)
[数据结构]B树及其基本操作、B+树的基本概念_第3张图片
[数据结构]B树及其基本操作、B+树的基本概念_第4张图片
[数据结构]B树及其基本操作、B+树的基本概念_第5张图片

三、B+树

B+树是一种数据结构,通常用于数据库和操作系统的文件系统中。B+树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+树元素自底向上插入,这与二叉树恰好相反。一棵B+树包含根结点、内部结点和叶子结点。
[数据结构]B树及其基本操作、B+树的基本概念_第6张图片

B+树是B树的一种变形形式,一棵m阶B+树的定义如下:
(1)结点的关键字个数=孩子个数-1
(2)B+树包含2种结点:内部结点(索引结点)和叶子结点。根结点可以是内部结点,也可以是叶子结点,根结点关键字个数至少一个。
(3)B+树的内部结点不保存数据,只用于索引,所有数据保存于叶子结点。
(4)m阶B+树内部结点最多有m-1个关键字(内部结点最多有m棵子树)
(5)内部结点的关键字也按B树那样从小到大排序,内部结点中的一个关键字,左子树中的所有关键字都小于它,右子树的关键字大于等于它。
(6)每个叶子结点都存有相邻叶子结点的指针,叶子结点本身关键字大小从小到大顺序链接

1、B+树的插入操作

(1)若为空树,创建一个叶子结点,记录插入,这个叶子结点也是根结点,插入操作结束
(2)针对叶子类型结点:根据关键字找到叶子结点,然后插入记录,插入后若当前结点关键字个数<=m-1,则插入结束。否则,将这个叶子结点分裂成为左右两个叶子结点,左叶子结点包括前m/2个关键字,右叶子结点包括剩下的,将第m/2+1个记录上移到父结点(必须索引结点)。进位到父结点的关键字左孩子指针指向左结点,右孩子结点指针指向右结点,本身就指向父结点。
(3)针对索引类型结点:若当前结点的关键字个数<=m-1,则插入结束。否则,将这个索引类型结点分裂成两个索引结点,左索引结点关键字包含前(m-1)/2个,右索引结点包含m-((m-1)/2)个,将第m/2个关键字上移到父结点中,类同第2步。

2、B+树的删除操作

如果叶子结点中没有要删除的关键字,则删除失败,否则执行下面步骤
(1)删除叶子结点中对应的关键字。删除后若结点关键字个数>=ceil(m/2)-1,删除操作结束,否则执行下一步
(2)若兄弟结点的关键字个数>ceil(m/2)-1,向兄弟结点借一个关键字,同时用借的关键字替换(当前结点与父结点相同的关键字),删除结束,否则执行下一步。
(3)当前结点与兄弟结点合并成新的叶子结点,并删除父结点中的关键字(孩子指针变成一个指针,正好指向新的叶子结点),当前结点指向父结点(索引结点)。执行下一步。
(4)若索引结点的关键字个数>=ceil(m/2)-1,则删除操作结束,否则执行下一步。
(5)若兄弟结点关键字个数>ceil(m/2)-1,父结点关键字下移,兄弟结点关键字上移,删除结束,否则执行下一步。
(6)当前结点和兄弟结点及其父结点关键字下移合并成新的结点,将新结点指向父结点,重复第4步。

四、参考文献

1、如果本文章满足不了大家的要求,觉得还要深入理解,请参考一位大佬的文章《从B树、B+树、B*树谈到R树》:https://blog.csdn.net/v_JULY_v/article/details/6530142
2、https://www.cnblogs.com/nullzx/p/8729425.html
3、《数据结构》

你可能感兴趣的:(数据结构与算法)