数据结构(十)优先级队列

一、需求与动机

元素接受访问的次序按照优先级,而非FIFO

 

场景

夜间门诊

病情危急的优先治疗

多任务调度

每个任务都有一个指标,指标都是动态变化的,操作系统总是挑选指标最大的任务交由CPU处理

 

应用、算法与特点

 

问题模式:

 

 

接口规范

 

 纯虚函数

 

a2基本实现

基于向量

 

 

有序向量

 

 

基于列表

 

 

有序列表

 

 

 

BBST

 

 

 

b1完全二叉堆:结构

在向量和树之间找一个折中的结构

完全二叉树

Complete Binary Tree

平衡因子处处非负的AVL

 

 

 

 

结构性

逻辑上,等同于完全二叉树

物理上,直接借助向量实现

 

 逻辑节点与物理元素,依层次遍历次序彼此应对

 

 对于向量中任意秩为i的元素,如果父节点存在,其秩为i-1再除以2,比如秩为11和12的元素,父节点存在,编号为5

如果秩为i的元素,有左孩子,左孩子的秩是两倍的i再加1,比如,对于6而言,左孩子为13

如果秩为i的元素,有右孩子,右孩子的秩是(i+1)*2,比如6的右孩子为14

 

利用C++的多重继承

 

 

堆序性

数值上,只要0<i,必满足

 

 即任何一个节点在数值上不会超过父亲

上面的图是秩,不是值

最大元只可能是根节点

 

 

b2完全二叉堆:插入与上滤

算法

为插入词条e,只需将e作为末元素接入向量

//结构性自然保持

//若堆序性也未破坏,则完成

 

否则 //只能是e与其父节点违反堆序性

e与其父节点换位 //若堆序性因此恢复,则完成

 

否则 //依然只能是e与其(新的)父节点违反堆序性

e再与其父节点换位

 

 不断重复...直到

e与其父亲满足堆序性,或者e到达堆顶点(没有父亲)

这一过程,就是所谓的上滤(percolate up)

 

实例

这里所标注的数值都是元素的优先级而非其所对应的秩

 

 由5个词条构成的完全二叉堆,上面的完全二叉树是逻辑结构,下面是物理上对应的向量结构,物理上的向量首元素是逻辑上完全二叉树的根节点,根据约定是数据集中的最大值

插入为5的词条

作为末元素插入到向量中,在逻辑上等效于在完全二叉树的底层向右侧拓展了一个节点,这种拓展没有破坏完全二叉堆的结构性,新引入的词条和父亲违背堆序性,二者互换位置。物理上是在向量中进行的

 

 交换后

 仍与上层的父亲违反堆序性

继续交互位置

 

交换后

 

 

实现

 

 

效率

 

b3完全二叉堆:删除

最大元素始终在堆顶,故为删除之,只需

摘除向量首元素,代之以末元素e

//结构性保持;若堆序性依然保持则完成

否则 //即e与孩子们违背堆序性

  e与孩子中的大者互换

  //若堆序性因此恢复,则完成

否则 //即e与其(新的)孩子们...

   e再次与孩子中的大者换位

 

 

 

 下滤

 

实例

删除最大元5

 

 1移动到根,左右孩子都必它大,局部违反了堆序性,其他地方保持堆序性

找到相对更大的4,互换位置,下滤

 

 交换后,依然每符合堆序性,1和2互换

 

 交换后

 

 

实现

 

 

b4完全二叉堆:批量建堆

自上而下的上滤

 

 

效率

 

 

自下而上的下滤

 

 

实例

由9个节点构成的完全二叉树

在物理上的向量图,最末尾内部节点所对应的秩应该为9/2下整减1,即3,下面节点上的3是值,纯属巧合

初始情况下每个叶节点都可以认为自成为一个子堆,画紫圈的部分形成了典型的模式,一个局部子树根,以及左右两个子堆,任务是左右子堆合并

 

 对局部子树根节点3进行下滤

 

 接下来往前一个的内部节点,6,对局部子树根6进行下滤; 接下来轮到内部节点1,对1下滤

 

对根节点做下滤,完成最终的合并

 

 效率

 

 

c堆排序

选取

 

 就地

 

 实现

 

 

实例:建堆

 

 几次下滤后,最终得到了完全二叉堆

 

选取+调整

开始整个向量都是未排序的部分,已排序的部分为空

令堆顶与末元素互换位置

 

 互换后,已排序序列有第一个元素5,黑色; 新的堆顶做下滤调整

 

剩下的四个元素依然恢复为一个堆,尽管规模减1个单位;最大元素4成为新的堆顶

 

 将堆顶与末元素1互换

 

 将堆顶摘出,归入到已排序序列中;下滤调整,保证是合法的堆

 

 堆顶3与末元素2互换,堆顶摘出,归入到有序序列中

 

 重复步骤

 

 

xa1左式堆:结构

引入左式堆,为了完成堆合并

 

堆合并

 

 单侧倾斜

 

 空节点路径长度

 

 左倾性&左式堆

 

 右侧链

 

 

xa2左式堆:合并

LeftHeap

不满足结构结构性,物理结构不再保持紧凑型,不使用向量,使用树

 

 算法

 

 实例

两个堆合并

 

 前者树根大于后者树根,无需互换,17为a,15为b,a的右孩子12

转为右子堆与b堆的合并问题

 

比较两个子堆的根节点,15大于12,互换名称,前者记作b,后者记作a

 

 

 a、b堆合并; a的右子树是8

 

转化为子堆8和子堆12合并

 两者应互换名称

 

 a右孩子为空,在接下来的递归层次上,直接返回节点8,并将8作为节点12的右孩子

左倾,左右子堆互换位置

递归返回到节点15

 

 15左右NPL都为1,左倾性没有破坏,逆行而上,到17,左孩子NPL为1,右为2

经过一次对换,交换17节点的左右孩子

 

xa3左式堆:插入与删除

insert()

 

 delMax()

 

转载于:https://www.cnblogs.com/aidata/p/11581875.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值