当前课程知识点:数据结构(下) > 第十章 优先级队列 > (b3)完全二叉堆:删除与下滤 > 10b3-1: 算法
接下来的这一节我们来讨论一下完全二叉堆的元素删除算法。
我们知道,对于优先级队列而言,内容读取操作只限定于特定的节点。
具体来说,只能是获取最大元或者删除最大元。
我们也知道,得益于堆序性,完全二叉堆中的最大元必然就是堆顶。
因此,如果只是需要获取这个元素,我们只需常数的时间。
然而为了删除这个节点,我们却需要做更多额外的工作。
首先,我们自然是将这个节点在物理上摘除掉,
当然此后在逻辑上这就不再是一棵结构完整的完全二叉树。
为尽快恢复结构性,我们不妨将末元素移送到首元素的位置上,以取代这个被摘除的堆顶。
经如此处理之后,结构性的确得以恢复,然而堆序性却有可能因此遭受破坏。
我们来观察一下,在将末元素前移至堆顶之后,
在那些位置有可能会违背堆序性呢?
从图中不难看出,唯一的可能只能是这个新的堆顶节点与它的孩子们违反堆序性。
那么,如何加以修复呢?
没错,交换。
如果e的确小于它的至少一个孩子,我们就将它与其中更大的那个孩子互换位置,
交换之后的情况应该是这样。
可以看到,在经过这样一次交换之后,在最高的层次上已经不再会出现逆序的情况。
当然,其它的节点也依然会维持原有的堆序性。
然而故事可能依然没有完结,因为下降一层之后的e又会有新的孩子,
而且如果不幸,它有可能至少会小于两个孩子中的某一个。
你看得出来如何解决这个新的难题吗?
没错,依然是交换。
在这种情况下,我们需要将e和它更大的那个孩子进行交换。
就这个例子而言,交换的结果应该是这样。
当然,经过这样的一次交换之后,在这个层次以上的所有逆序缺陷都应该得以修复。
然而不幸的是,在e下降一层之后,在接下来的这个层次上会有可能再次发生逆序。
不过我们对此已经习以为常了。果真出现这种情况的话,我们也可以故伎重演,
令e和它更大的那个孩子进行交换。就这个例子而言,交换之后的结果是这样。
当然这种情况的确可能会再次的以及持续的发生下去,
不过不要紧,每次出现这样的情况,我们都可以通过交换加以解决。
与节点的插入过程相仿,这里也存在某种单调性。
在原本最底层的节点e被前置为堆顶之后,每经过一次交换,它都会下降一层。
这就意味着尽管逆序的情况有可能持续地发生,但问题出现的高度必然会持续地下降。
因此这样一个过程也形象地称之为“下滤”(percolate down),
正是得益于这种不断下降的单调性,我们才可以保证这个算法必然终止。
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)希尔排序:逆序对
-本章测验
--本章测试