当前课程知识点:数据结构(下) > 第十章 优先级队列 > (b4)完全二叉堆:批量建堆 > 10b4-3: 自下而上的下滤:算法
为了得到改进的建堆算法,我们需要来考察这样一个典型的场景:
假设已经有了两个初始的堆H_0与H_1,
而它们的堆顶r_0与r_1分别作为p的左孩子与右孩子。
对于这样一种情况,在这种情况下,
我们应当如何迅速地将这两个堆合并起来,从而构成一个更大的堆呢?
实际上这并不是什么新问题。你能看得出来吗?
是的,完全二叉堆的delMax算法。
在那个算法当中,我们首先需要将最大元,也就是堆顶摘除掉,然后用向量中当前的末元素来取而代之
是的,我们就来考察刚刚取而代之的那个时刻。在那样一个时刻,难道不恰好就是我们所说的这样一个场景吗?
我们来验证一下,作为此前完全二叉堆的一部分,它们依旧处处满足堆序性和结构性。
因此,它们都各自成为一个堆。同时,它们也是新的这个根节点的子堆。
如果你能看透这一点,也就自然能得到相应的调整算法。
没错,我们只需套用此前delMax算法的后半部分,具体来说,就是对这个新的根节点做一次下滤:
当然,下滤的方向可能有两个:或者沿着左路的分支进入左侧的子堆,或者沿着右路的分支进入右侧的子堆。
无论如何,一旦节点p的下滤得以完成,原先的两个子堆也自然地完成了合并。
将这种处理手法推而广之并反复使用,我们就可以得到一个效率更高的批量建堆。
这个算法出自Floyd之手,该算法处理节点的次序与此前的蛮力算法恰好相反,
也就是说,在树中应该是自下而上、自右而左逐个处理。
而对于每一个节点,我们都只需做一趟下滤,
当然,对叶子节点而言,下滤并没有实际的意义,因此这个算法只需考虑所有的内部节点。
相应地,第一个接受处理的也应当是最后一个内部节点。
如果全堆的规模为n,那么最末尾的内部节点在向量中的秩就应当是floor(n/2)-1。
我们刚才已经看到,对每一个内部节点实施的下滤
其实质效果等同于将左右子堆合并起来,因此这样一个自下而上,逐个下滤的过程
也就等效于各子堆逐层向上合并,规模不断增加的过程。
因此最终当根节点的下滤也完成之后,所有节点也自然在整体上构成了一个完全二叉堆。
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)希尔排序:逆序对
-本章测验
--本章测试