优先级队列,顾名思义,它首先应该是一个队列。我们前面讲过,队列最大的特性就是先进先出。不过,在优先级队列中,数据的出队顺序不是先进先出,而是按照优先级来,优先级最高的,最先出队

如何实现一个优先级队列呢?

方法有很多,但是用堆来实现是最直接、最高效的。这是因为,堆和优先级队列非常相似。一个堆就可以看作一个优先级队列。很多时候,它们只是概念上的区分而已。往优先级队列中插入一个元素,就相当于往堆中插入一个元素;从优先级队列中取出优先级最高的元素,就相当于取出堆顶元素。

举个例子

1. 合并有序小文件
假设我们有 100 个小文件,每个文件的大小是 100MB,每个文件中存储的都是有序的字符串。我们希望将这些 100 个小文件合并成一个有序的大文件。这里就会用到优先级队列。

整体思路有点像归并排序中的合并函数。我们从这 100 个文件中,各取第一个字符串,放入数组中,然后比较大小,把最小的那个字符串放入合并后的大文件中,并从数组中删除。

假设,这个最小的字符串来自于 13.txt 这个小文件,我们就再从这个小文件取下一个字符串,放到数组中,重新比较大小,并且选择最小的放入合并后的大文件,将它从数组中删除。依次类推,直到所有的文件中的数据都放入到大文件为止。

这里我们用数组这种数据结构,来存储从小文件中取出来的字符串。每次从数组中取最小字符串,都需要循环遍历整个数组,显然,这不是很高效。有没有更加高效方法呢?

这里就可以用到优先级队列,也可以说是堆。我们将从小文件中取出来的字符串放入到小顶堆中,那堆顶的元素,也就是优先级队列队首的元素,就是最小的字符串。我们将这个字符串放入到大文件中,并将其从堆中删除。然后再从小文件中取出下一个字符串,放入到堆中。循环这个过程,就可以将 100 个小文件中的数据依次放入到大文件中。

我们知道,删除堆顶数据和往堆中插入数据的时间复杂度都是 O(logn),n 表示堆中的数据个数,这里就是 100。是不是比原来数组存储的方式高效了很多呢?

2. 高性能定时器
假设我们有一个定时器,定时器中维护了很多定时任务,每个任务都设定了一个要触发执行的时间点。定时器每过一个很小的单位时间(比如 1 秒),就扫描一遍任务,看是否有任务到达设定的执行时间。如果到达了,就拿出来执行。


但是,这样每过 1 秒就扫描一遍任务列表的做法比较低效,主要原因有两点:第一,任务的约定执行时间离当前时间可能还有很久,这样前面很多次扫描其实都是徒劳的;第二,每次都要扫描整个任务列表,如果任务列表很大的话,势必会比较耗时。

针对这些问题,我们就可以用优先级队列来解决。我们按照任务设定的执行时间,将这些任务存储在优先级队列中,队列首部(也就是小顶堆的堆顶)存储的是最先执行的任务

这样,定时器就不需要每隔 1 秒就扫描一遍任务列表了。它拿队首任务的执行时间点,与当前时间点相减,得到一个时间间隔 T。

这个时间间隔 T 就是,从当前时间开始,需要等待多久,才会有第一个任务需要被执行。这样,定时器就可以设定在 T 秒之后,再来执行任务。从当前时间点到(T-1)秒这段时间里,定时器都不需要做任何事情。

当 T 秒时间过去之后,定时器取优先级队列中队首的任务执行。然后再计算新的队首任务的执行时间点与当前时间点的差值,把这个值作为定时器执行下一个任务需要等待的时间。

这样,定时器既不用间隔 1 秒就轮询一次,也不用遍历整个任务列表,性能也就提高了。

思考

  • 往堆中插入元素的时间复杂度和往数组中插入元素的时间复杂度有区别?

总结

  • 优先级队列可以用实现

堆的应用之优先级队列相关推荐

  1. 二叉堆详解实现优先级队列

    二叉堆详解实现优先级队列 文章目录 二叉堆详解实现优先级队列 一.二叉堆概览 二.优先级队列概览 三.实现 swim 和 sink 四.实现 delMax 和 insert 五.最后总结 二叉堆(Bi ...

  2. 二叉堆(TopK问题,优先级队列)

    目录 实现一个大根堆 优先级队列 Comparable和Compator区别 compareTo方法 TopK问题 TopK问题常见题型为求最大(最小)的K个值. 我们一般拿堆来解决. 堆:二叉堆首先 ...

  3. 堆(优先级队列)及TOPK问题详解

    文章目录 1.二叉树的顺序存储 1.1存储方式 1.2下标关系 2.堆的应用:优先级队列(默认小根堆) 2.1概念 2.2Java中优先级队列的简单介绍 3.Topk问题 3.1求N个数中前k个最大/ ...

  4. 优先级队列 Python

    文章目录 环境 文章介绍 一.queue (线程安全) 3种不同的队列 1. Queue, 先进先出队列(FIFO) 2.LifoQueue(派生自Queue), 先进后出队列(LIFO) 3.Pri ...

  5. 使用最小堆使用优先级队列(c语言版本)

    下面的例子来自Weiss的<数据结构与算法分析:c语言描述>,自己亲自敲了一遍,跑了个demo,并将结果记录下来. binheap.h的头文件声明 //description: 使最小堆实 ...

  6. java 链表 最小堆优先级队列_关于Java集合的小抄

    List ArrayList 以数组实现.节约空间,但数组有容量限制.超出限制时会增加50%容量,用System.arraycopy()复制到新的数组,因此最好能给出数组大小的预估值.默认第一次插入元 ...

  7. 树形结构:优先级队列,堆

    优先级队列,堆是比较常用的数据结构,分支限界法,贪心法均会用到优先级队列 有必要了解一下优先级队列的实现方式 # -*- coding: utf-8 -*-# 最大堆# 很显然这是一个双针模型,指着一 ...

  8. 优先级队列 c语言,使用最小堆使用优先级队列(c语言版本)

    下面的例子来自Weiss的<数据结构与算法分析:c语言描述>,自己亲自敲了一遍,跑了个demo,并将结果记录下来. binheap.h的头文件声明 //description: 使最小堆实 ...

  9. 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority Queue)

    堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...

最新文章

  1. mysql 最长字符串_那些年的Mysql
  2. php 失去 焦点 另一个表单猎取值,同一表单如何根据某一个文本框的值 改变另一个文本框的值...
  3. Logistic Regression逻辑回归的简单解释
  4. 【面试题】HashMap 面试 21 问
  5. SAP中方会计凭证打印解决方案
  6. ORACLE常用监控语句(未完待续)
  7. Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition(SPP-net)
  8. 特征选择和特征提取,及其分类
  9. 拼多多爆款商品采集工具
  10. 韩国严厉监管元宇宙相关企业
  11. 一加手机怎么root权限_一加手机怎么获取root权限?
  12. Raspberry Pi (树莓派) - 图形化界面启动和命令行界面启动
  13. laravel跨域问题
  14. PyTorch中 nn.Conv2d与nn.ConvTranspose2d函数的用法
  15. 自然语言推理入门:ESIM
  16. 2018ICPC徐州赛区网络预赛
  17. 挤奶牛Crowded Cows 洛谷p3088
  18. 智能与人机融合智能的思考
  19. 机器学习 第三节 第八课
  20. 基于SpringBoot视频学习系统|视频点播系统的设计与实现【Java毕业设计·安装调试·代码讲解·文档报告】

热门文章

  1. GB28181---XML解析
  2. python后端教程_Python学习教程(技术干货):关于前后端分离开发入门
  3. Android Studio实现功能丰富的仓库管理系统
  4. 模板模式 php,PHP设计模式5-模板模式
  5. 南京工业大学计算机研究生分数,2019南京工业大学研究生分数线汇总(含2016-2019历年复试)...
  6. androidstudio4.1.1 build model卡主_在C++中加载PyTorch1.4的FasterRCNN模型
  7. python支持复数以及相关的运算吗_Python复数属性和方法运算操作示例
  8. 电子电路分析与设计:数字电子技术_红外气体传感器电子电路设计
  9. 怎样有效的学会php,十天学会PHP - 序2,有效的学习方法 (20180822-1)
  10. c语言输出字母随机数,你好,怎样用c语言输出一个1到100的随机数