当前课程知识点:数据结构(下) > 第八章 高级搜索树(下) > (b5)B-树: 删除 > 08B5-4 实例演示
接下来 我们就通过几个实例加深对B树算法过程的理解
首先 确认这是一棵5阶B树
其特征是节点内所含的关键码数最多为4
而除根节点外的其它节点 所含关键码至少有两个
现在 假设 我问你删除249
为此 我们首先需要通过查找 定位其所属的节点
接下来 将这个关键码从该节点中剔除掉
导致这个节点发生下溢
我们知道在修复下溢时 我们并不急于去做合并
而应该首先左顾右盼
的确 此时的右兄弟包含四个关键码 足以借出一个
当然 我们也知道 这种借出是迂回的
具体来说 下溢节点应该首先向 它的父节点借出268
而右兄弟的最左侧关键码315 则应该转而交给父亲
填补268留下的空缺
这也就是我们所说的旋转
请注意 果真若是发生了旋转 不仅原下溢节点会得到修复
其余所涉及的节点 无论兄弟 还是父亲
都不致因此继而发生下溢 因此这种解决方案是彻底的
也就是说 整个删除操作至此顺利结束
当然 还有其它的可能
比如 我们可能会接下来需要删除619
同样的 为此我们需要经过查找 确定619所属的那个节点
然后将这个关键码从这个节点中剔除掉
可以看到 在损失了一个关键码之后这个节点发生了下溢
为了修复这一缺陷 我们首先要站在这个节点的角度左顾右盼
然而 很遗憾 它没有左兄弟 而右兄弟虽然存在
但可惜自己已经处于即将下溢的边缘临界状态
并不足以借出任何关键码
也就是说 旋转的技巧在此并不可行
我们只得借助另一技巧 也就是合并
这等同于分裂的逆过程
就这个例子而言 我们需要从这两个节点的父节点中找到
介于它们之间的那个关键码 也就是703
并且将这个关键码取出下移 作为粘合剂
将这两个节点合二为一
具体过程 如这个动画所示
请注意 尽管此前位于最底层的下溢缺陷得到了修复
但是更高一层的这个父节点 却随即也发生了下溢
为了修复这一缺陷 我们依然需要站在这个节点的角度左顾和右盼
情况与刚才居然类似 没有右兄弟
而左兄弟呢 依然因为处于下溢的临界状态 而无法借出任何关键码
因此 我们不得不再次求助于第二种技巧 也就是合并
具体来说 需要从父节点
也就是此时的树根中找到介于下溢节点及其兄弟之间的那个关键码
可以注意到其实此时根节点只含有唯一的一个关键码 528
尽管如何 我们也需要将这个关键码取出 并且下移
作为粘合剂 将下一节点及其兄弟
粘合起来 构成一个合法的节点
整个过程如下
可以看到 的确如我们所期望的
在这一层上的下溢缺陷 的确得到了修复
然而接下来出现的问题是
原先只包含唯一关键码的那个根节点 现在却变成空的了
我们知道 在B树中 根节点拥有特权 只需拥有两个分支即可
但即便如此 却不可能只拥有一个分支
实际上 这样一个根节点是没有任何实际用处的
因此这时 我们不妨将它删除
而用刚才经合并所得的这个节点取而代之 作为新的树根节点
因此结果是这样 可以看到 整棵B树的高度 因此降低了一层
这也是B树高度得以下降的唯一可能
具体来说 在删除节点之后 需要进行合并操作
而且这种合并操作会不断的向上蔓延 直到树根
而树根节点只含有唯一的一个关键码
以致于在借出这个关键码之后 树根成为空节点
同样需要说明的是 尽管这种最坏情况不难构造出来
但在实际运转过程中 却是十分罕见的
关于这一方面的分析 你可以参照我们的习题解析
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)概述
--07A-1 纵览
--07A-5 接口
-(a)概述--作业
-(b1)BST:查找
-第七章 二叉搜索树--(b1)BST:查找
-(b2)BST:插入
-(b2)BST:插入--作业
-(b3)BST:删除
-第七章 二叉搜索树--(b3)BST:删除
-(c)平衡与等价
-(c)平衡与等价--作业
-(d1)AVL树:重平衡
-第七章 二叉搜索树--(d1)AVL树:重平衡
-(d2)AVL树:插入
-(d2)AVL树:插入--作业
-(d3)AVL树:删除
-(d3)AVL树:删除--作业
-(d4)AVL树:(3+4)-重构
-(d4)AVL树:(3+4)-重构--作业
-本章测验
--章节测验
-(a1)伸展树:逐层伸展
--习题
-(a2)伸展树:双层伸展
--习题
-(a3)伸展树:算法实现
--习题
-(b1)B-树:动机
--习题
-(b2)B-树:结构
--习题
-(b3)B-树:查找
--习题
-(b4)B-树: 插入
--习题
-(b5)B-树: 删除
--习题
-(xa1)红黑树:动机
--习题
-(xa2)红黑树:结构
--习题
-(xa3)红黑树:插入
--习题
-(xa4)红黑树:删除
-本章测验
--习题
-(b)散列:原理
--09B-3 数组
--09B-4 原理
--09B-5 散列
--09B-6 冲突
--习题
-(c)散列:散列函数
--习题
-(d1)散列:排解冲突(1)
--习题
-(d2)散列:排解冲突(2)
--习题
-(e)桶/计数排序
--习题
-本章测验
--本章测试
-(a1)需求与动机
--习题
-(a2)基本实现
--习题
-(b1)完全二叉堆:结构
--习题
-(b2)完全二叉堆:插入与上滤
--习题
-(b3)完全二叉堆:删除与下滤
--习题
-(b4)完全二叉堆:批量建堆
--习题
-(c)堆排序
--习题
-(xa1)左式堆:结构
--习题
-(xa2)左式堆:合并
--习题
-(xa3)左式堆:插入与删除
-本章测验
--本章测试
-(a)ADT
--习题
-(b1)串匹配
--习题
-(b2)蛮力匹配
--习题
-(c1)KMP算法:从记忆力到预知力
--习题
-(c2)KMP算法:查询表
--习题
-(c3)KMP算法:理解next[]表
--习题
-(c4)KMP算法:构造next[]表
--习题
-(c5)KMP算法:分摊分析
--习题
-(c6)KMP算法:再改进
-(d1)BM_BC算法:以终为始
-(d2)BM_BC算法:坏字符
-(d3)BM_BC算法:构造bc[]
-(d4)BM_BC算法:性能分析
-(e1)BM_GS算法:好后缀
-(e2)BM_GS算法:构造gs表
-(e3)BM_GS算法:综合性能
-(f1)Karp-Rabin算法:串即是数
-(f2)Karp-Rabin算法:散列
-本章测验
--本章测试
-(a1)快速排序:算法A
-- 12a1-5: 实例
--习题
-(a2)快速排序:性能分析
--习题
-(a4)快速排序:变种
-(b1)选取:众数
-(b3)选取:通用算法
--习题
-(c1) 希尔排序:Shell序列
--习题
-(c2)希尔排序:逆序对
-本章测验
--本章测试