当前课程知识点:数据结构(下) > 第八章 高级搜索树(下) > (b5)B-树: 删除 > 08B5-2 旋转
首先 请确认 若节点v果真刚刚发生下溢
那么它应该恰好包含m/2-1个分支 以及m/2-2个关键码
是的 刚刚发生下溢的节点V应该恰好只包含m/2-2个关键码
联想到在插入算法中 通过分裂来解决上溢问题
你可能会首先想到通过合并来解决下溢问题
是的 这只是可供选择的预案之一
但优先级更高的 并不是它
事实上 这个刚刚下溢的节点会首先左顾右盼
如果有某一兄弟拥有足够多个关键码
比如不失一般性 假设它的左兄弟存在
而且这个兄弟所拥有的关键码数不少于m/2的上整
那么它的这个左兄弟 就有可能向V借出一个关键码
这里你需要核算一下 在这种情况下
左兄弟向V借出一个关键码之后
既可解决V的下溢问题 同时自己也不至因此而发生下溢
这个构思非常的好 可惜有一点小小的难题需要解决
我们知道 如果的确存在这样的两个兄弟
那么它们的父亲也必然存在
而且在它们的父亲中必然有一个关键码 比如说y
会介于它们之间
作为搜索树 B树同样应该符合中序遍历意义上的顺序性
这就意味着 作为左子树中的一元
L中的所有关键码 都应该小于y
对称地 作为右子树中的一元 V中的所有关键码都应该大于y
因此 将L中的任何一个关键码 直接移送到V中
都将破坏这一局部 乃至全局的顺序性
这是万万不可的
然而 反过来 这里的技巧也恰在于此
这样一种转借的思路 关键在于
我们需要借助关键码y 曲线地转借
就像所谓的三角借债一样
实际上 V并非是直接向它的左兄弟去借入一个关键码
而是从它的父节点中 去借出y这个关键码
你没听错 的确是从父节点中去借出一个关键码
不难想象到 在借出了这个关键码之后
父节点在y这个位置上应该会出现一个空缺
然而 这并不要紧 不要忘了 这里还有一个节点L
它还足以向父节点借出一个关键码 以填补刚才所留出的空当
问题是 在L中 应该借出谁呢?
是的 应该借出的是在其中数值最大
从图中看 位于最右侧的这个关键码 我们不妨称之为x
这样 在经过了连续的两次借出之后
节点V从父节点处获得了一个关键码y 使得自己不再下溢
同时 父节点也从左侧节点中 借入了一个关键码x
从而实现了收支的平衡
同时 左侧的这个兄弟节点L
也并没有因为损失一个关键码 发生下溢
更重要的是 经过了这样一种貌似曲折的转借
局部乃至全局的顺序性 依然得到了延续
整个变化过程 可以化作关键码y被转移至节点V
而关键码x则从L 转移至P
因此 也不妨形象的将这种调整 称作旋转
当然 只要下一节点V拥有一个满足同样条件的右兄弟R
我们也可以通过对称的旋转来修复下溢
然而很遗憾 这样的左兄弟和右兄弟 未必存在
一种极端情况是 V的左右兄弟 或者不存在
或者不足以借出任何的关键码
对于这样的情况 我们又当如何应对和处置呢?
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)希尔排序:逆序对
-本章测验
--本章测试