Java优先级队列PriorityQueue

news2024/9/21 3:29:32

概述

        优先级队列PriorityQueue是队列接口Queue的一种实现,能够以O(logn)的时间复杂度实现元素的插入和删除。PriorityQueue不是一个标准的队列,因为它保存元素的顺序不是按照元素入队的顺序,而一个是按元素的大小重新排序的,这已经违反了队列先进先出(FIFO)的基本规则。PriorityQueue是一种具有特殊用途的数据结构,它总能保持队首元素是队列中最大的,这个特性使得PriorityQueue在需要基于优先级处理任务的场景下非常有用,比如在调度算法、事件驱动编程、优先级排序等应用中。

        想要每次都能从队列中获取最大元素通常能想到的方式有两种:比如元素无序保存,出队时遍历一遍队列找出最大元素,这种方式元素入队的时间复杂度为O(1),出队的时间复杂度为O(n);或者是元素按顺序保存,出队时直接取队首元素,这种方式元素入队的时间复杂度为O(n),出队的时间复杂度为O(1);由于这两种方式都不能兼顾元素入队出队的效率,于是便有了基于二叉堆的实现方式。

完全二叉堆

        PriorityQueue内部实现通常采用堆数据结构,具体来说,是一个完全二叉堆,它在结构上是完全二叉树的形式,也就是说,除了最后一层可能不满外,每一层都是完全填充的,且最后一层的所有结点都尽可能地靠左排列。完全二叉堆分为两种类型:最大堆和最小堆。

最大堆:在最大堆中,每个父节点的值都大于或等于其子节点的值。因此,堆的根节点总是包含堆中的最大值。

最小堆:在最小堆中,每个父节点的值都小于或等于其子节点的值。所以,堆的根节点存储的是堆中的最小值。

        完全二叉堆主要操作包括元素插入和删除:插入的新元素总是被添加到完全二叉树的最后一层的最右侧的空位置,然后通过上滤(swim)过程调整堆,以维护堆的性质。删除操作通常涉及移除堆顶元素,然后将堆的最后一个元素移动到堆顶位置填补空缺,并通过下滤(sink)过程调整堆。完全二叉堆由于其高效的特性(插入和删除O(logn)时间复杂度),常被用于实现优先队列等数据结构和各种算法中,比如堆排序、TopN问题等。堆的详细介绍请参考数据结构:堆

优先级队列的使用

PriorityQueue简单示例:
// 创建一个空的优先级队列
PriorityQueue<Integer> queue = new PriorityQueue<>();
// 添加元素
queue.offer(5);
queue.offer(3);
queue.offer(7);
queue.offer(1);
// 元素出队
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());

输出为1、3、5、7。元素插入是无序的,输出按从小到大排序,可见这是一个最小堆实现的优先队列,也可以通过向构造器传入参数实现降序排序。

定制排序:
// 创建一个空的优先级队列并传入排序规则
PriorityQueue<Integer> queue = new PriorityQueue<>(Comparator.reverseOrder());
// 添加元素
queue.offer(5);
queue.offer(3);
queue.offer(7);
queue.offer(1);
// 元素出队
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
//输出为7、5、3、1
使用集合初始化优先队列:
//创建一个优先级队列并使用List初始化
PriorityQueue<Integer> queue1 = new PriorityQueue<>(Arrays.asList(3,1,7,5));
//创建一个优先级队列并使用另一个队列初始化
PriorityQueue<Integer> queue2 = new PriorityQueue<>(queue1);
//创建一个优先级队列并使用set集合初始化
Set<Integer> set = new HashSet<>();
PriorityQueue<Integer> queue3 = new PriorityQueue<>(set);

Java标准库中实现了多种PriorityQueue的构造器,能够通过不同类型的集合快速地生成一个优先级队列,为程序员提供了便利,提升了应用开发的灵活性。

总结

PriorityQueue不遵循传统队列的FIFO原则,作为一种特殊的队列类型,它通过动态调整元素顺序,高效地支持了基于优先级的操作,是解决特定类型问题的强大工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2150994.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

标签云效果

产品要求&#xff0c;词云要实现动态滚动。查资料&#xff0c;改写效果。 echarts词云效果 传统的echarts-wordCloud不能满足需求。 标签云 换了标签云&#xff0c;以下是代码 <template><div class"mx-auto" :style"{ width: width px }"&g…

平凉锅盔,真的绝绝子

平凉&#xff0c;这座古老的城市&#xff0c;孕育出了一种令人赞叹的美食 —— 平凉锅盔。平凉锅盔&#xff0c;那是一种能瞬间勾起人们食欲的存在。远远望去&#xff0c;它如同一座金色的小山&#xff0c;散发着诱人的光泽。其外形圆润饱满&#xff0c;厚实的面饼给人一种踏实…

时代变了,MySQL 早已不是最流行的数据库了

以下文章来源于古时的风筝 &#xff0c;作者风筝 在StackOverflow 上看到2024年技术趋势&#xff0c;关于数据库的部分&#xff0c;PostgreSQL 是开发人员使用最多的数据库&#xff0c;超过 MySQL 了。虽然在国内好像不是这样。 PostgreSQL 在 2018 年的开发者调查中首次亮相…

极越联手百度这你受得了吗!SU7还能稳坐“7字辈”头把交椅?

文/王俣祺 导语&#xff1a;自从今年上半年小米SU7标榜为“年轻人的第一台纯电轿车”&#xff0c;各家车企全都坐不住了。尤其是与小米“颇有渊源”的吉利&#xff0c;从极氪再到领克&#xff0c;目标已经可以说是路人皆知了。现在极越07也来了&#xff0c;可以看出吉利也是下了…

Python游戏开发中的16个关键概念

大家好&#xff01;今天我们要聊的是Python游戏开发中的一些关键概念。无论是初学者还是有一定经验的开发者&#xff0c;了解这些概念都将有助于你更好地掌握游戏开发的基础。接下来&#xff0c;我们将从简单的概念入手&#xff0c;逐步过渡到更复杂的技巧。 文末有惊喜福利 1.…

如何选择适合客户运营团队的帮助中心搭建工具?8款工具盘点

在竞争激烈的商业环境中&#xff0c;客户运营团队需要高效、便捷的工具来搭建帮助中心&#xff0c;以提升客户服务质量和用户体验。选择合适的帮助中心搭建工具&#xff0c;不仅能提高团队工作效率&#xff0c;还能增强客户满意度和忠诚度。本文将为您盘点八款适合客户运营团队…

FC优化配置

1.集群扩容CNA时打开bmc 2.给rhel7虚拟机安装tools-需要重启虚拟机 3.FC上创建集群 资源池右击创建集群&#xff08;物理机大于10台&#xff0c;分业务类型创建集群&#xff09; &#xff08;解决集群内主机挂了&#xff0c;动态调整&#xff09; &#xff08;解决集群内个别…

vulnhub(11):derpnstink(hydra爆破用户名和密码、验证的文件上传)

端口 nmap主机发现 nmap -sn 192.168.159.120/24 ​ Nmap scan report for 192.168.159.120 Host is up (0.00020s latency). ​ 120是新出现的机器&#xff0c;他就是靶机 nmap端口扫描 nmap -Pn 192.168.159.120 -p- --min-rate 10000 -oA nmap/scan 扫描开放端口保存到 nma…

C#为任意组件开发登录功能的记录

非常简单&#xff0c;直接给出代码&#xff1a; 数据库操作类 这个无需多言就是简单的包含了数据操作的内容&#xff0c;允许你在这一个类中写完关于本地数据库或者云数据库操作的逻辑&#xff0c;与登录逻辑分开哦。 注意&#xff0c;如果你的软件要给别人运行使用&#xf…

电脑连接手机热点只能登陆qq和微信 浏览器无法正常上网的原因

电脑连接手机热点只能登陆qq和微信 浏览器无法正常上网的原因 浏览器有报错dns错误 但是火绒无法正常修复 DNS配置异常 chrome报错DNS_PROBE_FINISHED_BAD_CONFIG 错误原因在ipv4dns服务器他的地址,如果是自动获取 是192.168.208.143 和ipv4地址冲突,导致不正常,我查看本机…

【南方科技大学】CS315 Computer Security 【Lab3 Format String Vulnerability】

目录 Lab OverviewLab TasksTask 1: The Vulnerable ProgramTask 2: Understanding the Layout of the StackTask 3: Crash the ProgramTask 4: Print Out the Server Program’s MemoryTask 5: Change the Server Program’s MemoryTask 6: Inject Malicious Code into the Se…

【第十一章:Sentosa_DSML社区版-机器学习分类】

目录 11.1 逻辑回归分类 11.2 决策树分类 11.3 梯度提升决策树分类 11.4 XGBoost分类 11.5 随机森林分类 11.6 朴素贝叶斯分类 11.7 支持向量机分类 11.8 多层感知机分类 11.9 LightGBM分类 11.10 因子分解机分类 11.11 AdaBoost分类 11.12 KNN分类 【第十一章&…

С++第十三节课 string初体验

一、string类的相关函数 string实际上也就是一个管理字符的顺序表&#xff01; 如果我们需要遍历一个字符串&#xff0c;怎么实现&#xff1f; 我们可以通过下标访问操作符 size实现字符串的遍历&#xff01; int main() {string s1("hello world");// 遍历一个字…

玩具车检测系统源码分享

玩具车检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Visio…

zynq SDK 关于SD卡报错

在修改了BD的部分代码之后&#xff0c;重新综合工程生成bit&#xff0c;之后刷新hdf文件&#xff0c;在SDK端就出现了SD卡相关的函数未定义的报错&#xff1a; Description Resource Path Location Type E:\Work\VivadoPrj\Prj1\project_1\project_1.sdk\Test\Debug/…/src/hel…

arm开发板通信

c语言复习 查询Ubuntu版本&#xff08;18.04&#xff09;和内核&#xff08;5.4&#xff09; 查询使用软件的版本号 arm开发板通信- 直播视频-- 项目第二天下午 2024-09-20 linux和windows下操作开发板前提是开发板中已经导入系统 以下是具体操作 linux下开发板的操作 li…

Java项目实战II基于Java+Spring Boot+MySQL的读书笔记共享平台(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、论文参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在信息爆炸…

无人机黑飞打击技术详解

随着无人机技术的普及&#xff0c;无人机“黑飞”&#xff08;未经授权或违反规定的飞行&#xff09;现象日益严重&#xff0c;对公共安全、隐私保护及重要设施安全构成了严重威胁。为有效应对这一挑战&#xff0c;各国政府和安全机构纷纷研发并部署了一系列无人机黑飞打击技术…

龙头名企HR数字创新:超8成参调企业上线电子签

近日&#xff0c;法大大与人力资源智享会&#xff08;以下简称“智享会”&#xff09;联合发布了《第七届人力资源共享服务中心研究报告》&#xff08;点击阅读及下载&#xff1a;最新&#xff01;《第七届人力资源共享服务中心研究报告》重磅来袭&#xff09;&#xff0c;该报…

反转字符串中的单词--力扣151

反转字符串中的单词 题目思路代码 题目 思路 题目的难点在于首先要清除多余的空格&#xff0c;并且单词之间要留一个空格&#xff0c;首单词前和末尾单词后不能有多余空格。我们使用双指针去除所有的空格&#xff0c;然后在处理完一个单词后手动加一个单词。具体思路是当快指针…