动态查找表-B树

 
在了解B树之前,先了解什么叫M叉排序树

M叉排序树

在这里插入图片描述
 

M叉排序树查找

查找62
62 > 50
指针往后移
在这里插入图片描述

62 < 70
62如果存在的话,一定会在70的左子树上
在这里插入图片描述
62 > 55
往后移
在这里插入图片描述
62 > 60
往后移
在这里插入图片描述
62 < 65
如果62存在的话,62一定在65的左子树上
在这里插入图片描述
62 > 61
往后移
在这里插入图片描述
62 == 62
查找成功
在这里插入图片描述
 
 
查找67
67 > 50
往后移
在这里插入图片描述
67 < 70
如果67存在的话,那么它一定在70的左子树上
在这里插入图片描述
67 > 55
往后移
在这里插入图片描述
67 > 60
往后移
在这里插入图片描述
67 > 65
如果67存在的话,那么它一定在65的右子树上
在这里插入图片描述
67 > 66
往后移
在这里插入图片描述
67 < 68
如果67存在的话,那么它一定在68的左子树上
在这里插入图片描述
结果为空
表中没有67这个结点
在这里插入图片描述
B树的查找过程与M叉排序树相同
 
 

B树的性质

1. 阶和度一个概念,不过B树是包含了叶结点,B树的叶结点为空,是不存在的
2. 除根结点外.所有非叶结点的关键字的取值范围为【m/2-1,m-1】
3. 除根结点外,所有非叶结点的子树可以为空,但如果有子树,则必须为【m/2,m】棵
4. 所有叶结点都在同一层(各子树没有高度差,绝对平衡)。叶结点不带信息,实际上不存在,可以看成查找失败的结点
5. 5阶的树的所有非叶结点的结构为nP0K1P0K1P1K2P2K3P3K4P4
K要按从小到大的顺序排列
P要比K多一个指针
6.所有叶子结点处在同一层,根结点到每个叶子结点距离相同

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
n为当前关键字的个数,p为子树指针,k为关键字指针
在这里插入图片描述
在这里插入图片描述
 

B树的插入

在这里插入图片描述
插入50、80
在这里插入图片描述
插入70
在这里插入图片描述
插入30
在这里插入图片描述

插入90
发现超出了B树的关键字的上限
在这里插入图片描述

此时有两种情况
设:超出范围的结点为B
1.当结点B的双亲结点(A)还有多余的位置时
将结点B的关键字m/2为中点, (m为新增了关键字后的数量)
(0,m/2-1)的关键字保持在原来的结点(B)中不变
(m/2+1,m)存放在一个新的结点(C)
将m/2存放到双亲结点中,然后修改指针
A(m/2)->lchild = B
A(m/2)->rchild = C

2.结点B的双亲结点(A)没有多余的位置时
操作1导致双亲结点的关键字也超出范围的话,则也需要对双亲结点做分裂操作,直到这个过程持续到根结点,如果根结点也超出了上限,则创建新的根结点,树的高度加1

在这里插入图片描述
m/2 = 3
已70为中点,
(30,50)存放在旧节点中
(80,90)存放在新节点中
因为是根结点,它没有双亲,自然双亲没有多余位置,所以创建一个新的结点,来存放70
然后连接左孩子和右孩子
在这里插入图片描述
插入20,25
在这里插入图片描述

插入40
超出了关键字上限,需调整
在这里插入图片描述
m/2 = 3
已30为中点,
(20,25)存放在旧节点中
(40,50)存放在新节点中
发现双亲结点还有多余位置,将m/2(30)存放到双亲结点中
然后连接左孩子和右孩子

在这里插入图片描述
插入81,85
在这里插入图片描述

插入88
超出了关键字上限,需调整
在这里插入图片描述
m/2 = 3
已85为中点,
(80,81)存放在旧节点中
(88,90)存放在新节点中
发现双亲结点还有多余位置,将m/2(85)存放到双亲结点中
然后连接左孩子和右孩子
在这里插入图片描述

插入93,94

在这里插入图片描述
插入98
超出了关键字上限,需调整
在这里插入图片描述
m/2 = 3
已93为中点,
(88,90)存放在旧节点中
(94,98)存放在新节点中
发现双亲结点还有多余位置,将m/2(93)存放到双亲结点中
然后连接左孩子和右孩子
在这里插入图片描述
插入60,65
在这里插入图片描述

插入68
超出了关键字上限,需调整
在这里插入图片描述
已60为中点,
(40,50)存放在旧节点中
(65,68)存放在新节点中
发现双亲结点没有多余位置了
在这里插入图片描述
因为是根结点没有多余位置
那么就需要对根结点做分裂操作
m/2 = 3
已70为中点,
(30,60)存放在旧节点中
(85,93)存放在新节点中
新建一个结点来存放m/2(70),来做为新的根结点
然后连接左孩子和右孩子
在这里插入图片描述
为什么根结点可以只有一个关键字?
在调整根结点时,就会把一个关键字提上去,
但如果根结点的关键字的取值范围也是【m/2-1,m-1】的话,这个操作就没办法完成
在这里插入图片描述
 
 

B树的删除

终端结点的删除

1.终端结点的关键字个数大于(m/2-1)

再删除关键字后,终端结点的关键字个数大于(m/2-1)
在这里插入图片描述
删除结点53
在这里插入图片描述
删除54
在这里插入图片描述

2.终端结点的关键字个数小于(m/2-1),且兄弟结点的个数大于(m/2-1)

在删除该结点上的关键字后,关键字的个数小于(m/2-1)不符合B树的性质
就需要做以下调整:
1.将双亲关键字移动到该结点上
2.将兄弟关键字移动到双亲结点上(左兄弟移最大的,右兄弟移最小的)
在这里插入图片描述

删除50
发现关键字个数不符合B树的性质
要向左/右兄弟(就算借一个也满足B的性质)借一个关键字过来
在这里插入图片描述
向右兄弟借关键字
但是不能直接借用左/右兄弟的结点,通过双亲结点中转一下,
将双亲关键字(60)转移到该结点上,
然后将右兄弟关键字(65)转移到双亲结点上
在这里插入图片描述
在这里插入图片描述

向左兄弟借关键字
在这里插入图片描述
30移下来,28移上去
在这里插入图片描述
 

3.终端结点的关键字个数小于(m/2-1),且兄弟结点的个数等于(m/2-1),双亲结点等于(m/2-1)

终点结点在删除了一个关键字后,个数小于(m/2-1),
并且兄弟结点如果借出一个关键字,个数也会小于(m/2-1)时

我们要需要做以下调整:
将该结点的关键字、双亲关键字、兄弟结点关键字合并起来
1.将双亲结点的关键字移动到该结点
2.将兄弟结点的所有关键字移动到该结点
如果这个操作导致了双亲结点关键字个数 < m/2-1,则继续合并双亲结点,直到根结点
在这里插入图片描述

删除28、25结点
该结点为1(不符合B树的性质),但兄弟结点的关键字为m/2-1,也借不了关键字
此时需要将该结点(20)、双亲关键字(28)和,兄弟结点(30,40)合并
在这里插入图片描述

在这里插入图片描述
此时,我们会发现双亲结点的关键字个数 < m/2-1,
继续合并
将该结点(60)、双亲关键字(70)和,兄弟结点(85,93)合并
在这里插入图片描述
指针整理一下
在这里插入图片描述
 

非终端结点删除

直接删除,用直接前驱或直接后继代替即可
当前,前驱或者后继所在的结点因为少了一个关键字,而导致不满足B树的性质,则需要进行终端删除的操作
在这里插入图片描述
删除70
70的直接前驱是69

在这里插入图片描述

删除69
在这里插入图片描述
69的后继是82
在这里插入图片描述
此时我们会发现,84这个关键字的结点不满足B树的性质,需要做调整
这时,我们又会发现,这个结点的兄弟结点的关键字数量等于m/2-1
因此,我们需要合并这个结点(84)、双亲关键字(85)和兄弟结点(88,90)
在这里插入图片描述
此时,93这个关键字的结点不满足B树的性质,需要做调整
这时,我们又会发现,这个结点的兄弟结点的关键字数量等于m/2-1
因此,我们需要合并这个结点(93)、双亲结点(82)和兄弟结点(30,60)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值