优先级队列(堆)

目录

优先级队列

1.概念

1. 堆的概念

2.堆的存储方式

3. 堆的创建

4. 建堆的时间复杂度

总结


 

 

 

优先级队列

1.概念

前面介绍过队列,队列是一种先进先出的数据结构。

d628525a32084971b7d596f3bc103ea0.png但有些情况下,操作的数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列,在该场景下,使用队列显然不合适,比如,在玩游戏的时候,如果有来电,系统会优先处理打进来的电话。

在这种情况下,数据结构应该提供两个基本的操作,一个是返回最高优先级对象,一个是添加新对象,这种数据结构是优先级队列(Priority Queue)。

a56527fe3a064e55b57cdaa71e5b13dc.png

 
2. 优先级队列的模拟实现

JDK1.8中的PriorityQueue底层使用了堆这种

数据结构,而堆实际就是在完全二叉树的基础上进行了一些调整。

 

1. 堆的概念

如果有一个 关键码的集合 K = {k0 k1 k2 kn-1},把它的所有元素 按完全二叉树的顺
 
序存 储方式存储 在一 个一维数组中,并满足: Ki <= K2i+1 Ki<= K2i+2 (Ki >= K2i+1 且
 
Ki >=K2i+2) i = 0,1,2…,则 称为 小堆(或大 堆)。将根节点最大的堆叫做最大堆或大根
 
堆,根节点最小的堆叫做最小堆或小根堆。
 
堆的性质:
 
●堆中某个节点的值总是不大于或不小于其父节点的值;
 
●堆总是一棵完全二叉树。
 
1eb6bdf1e7d244c9844fb5f6c1ac5bf6.png

9788f3eecce340f9bd5762ce32e857bc.png

 

 

2.堆的存储方式

从堆的概念可知, 堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储
aeb1ddc5dace469c85aa2e649595d0e7.png
 
注意:对于 非完全二叉树,则不适合使用顺序
方式进行存储,因为为了能够还原二叉树, 空间中必须要存储空节 点,就会导致空间利用率比较低
 
将元素存储到数组中后,可以根据二叉树章节的性质5对树进行还原。假设i为节点在数组中的下标,则有:
如果i为0,则i表示的节点为根节点,否则i节点的双亲节点为 (i - 1)/2
 
如果2 * i + 1 小于节点个数,则节点i的左孩子下标为2 * i + 1,否则没有左孩子
 
如果2 * i + 2 小于节点个数,则节点i的右孩子下标为2 * i + 2,否则没有右孩
 
 

3. 堆的创建

对于集合{ 27,15,19,18,28,34,65,49,25,37 }中的数据,如果将其创建成大根堆呢?
d9d26b0fb05a4daebe9383a86470b949.png
1. 让parent标记需要调整的节点,child标记parent的左孩子(注意:parent如果有孩子一定先是有左孩子)
 
2. 如果parent的左孩子存在即:即:child<usedSize, 进行以下操作,直到parent的左孩子不存在
 
 判断 parent右孩子是否存在,存在找到左右孩子中最大的孩子,让child始终指向最大值孩子
 
 将parent与较大的孩子child比较,如果:
 
   ●parent大于较大的孩子child,调整结束
 
   ●否则:交换parent与较大的孩子child,交换完成之后,parent中大的元素向下移动,可能导致子 树不满足堆的性质,因此需要继续向下调整,
 
     即parent = child;child = parent*2+1; 然后继续2。
代码实现
fe228af4edac4bfa8ffaed24d8223bd1.png
注意:在调整以 parent 为根的二叉树时,必须要满足 parent 的左子树和右子树已经是堆了才可以向下调整。
 
时间复杂度分析:
 
最坏的情况即图示的情况, 从根一路比较到叶子,比较的次数为完全二叉树的高度,即时间复杂度为
763b19d74a5b4395a3f7aa7329724b86.png

4. 建堆的时间复杂度

因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明(时间复杂
 
度本来看的就是 近似值,多几个节点不影响最终结果)
 
63a846892a4e40d59c69e279660c7d14.png 时间复杂度O(N)

 

总结

优先队列常使用完全二叉树实现,本文主要让大家了解优先级队列和堆的相关概念,并学会了堆的存储方式和堆的创建。关于堆的其他操作会在后续文章中讲解。

 

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值