优先级队列(Java )
目录
- 一、 优先级队列
- 1、概念
- 二、优先级队列的模拟实现
- 1、堆的概念
- 2、堆的存储方式
- 三、堆的创建
- 1、堆向下调整
- 2、堆的创建
- 3、建堆的时间复杂度
- 四、堆的插入与删除
- 1、堆的插入
- 2、堆的删除
- 五、用堆模拟实现优先级队列
一、 优先级队列
1、概念
优先级队列(Priority
Queue)是一种特殊的队列,它根据元素的优先级进行排序。优先级队列的实现通常依赖于堆数据结构,可以是最大堆或最小堆。
二、优先级队列的模拟实现
1、堆的概念
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
堆的性质:
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树。
2、堆的存储方式
从堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储
注意:对于非完全二叉树,则不适合使用顺序方式进行存储,因为为了能够还原二叉树,空间中必须要存储空节点,就会导致空间利用率比较低。
将元素存储到数组中后,可以根据二叉树章节的性质5对树进行还原。假设i为节点在数组中的下标,则有:
如果i为0,则i表示的节点为根节点,否则i节点的双亲节点为 (i - 1)/2
如果2 * i + 1 小于节点个数,则节点i的左孩子下标为2 * i + 1,否则没有左孩子
如果2 * i + 2 小于节点个数,则节点i的右孩子下标为2 * i + 2,否则没有右孩子
三、堆的创建
1、堆向下调整
我们来思考一个问题:对于集合{ 27,15,19,18,28,34,65,49,25,37 }中的数据,如果将其创建成堆呢?
仔细观察上图后发现:根节点的左右子树已经完全满足堆的性质,因此只需将根节点向下调整好即可。
向下过程(以小堆为例):
- 让 parent 标记需要调整的节点, child 标记 parent 的左孩子 (注意:parent如果有孩子一定先是有左孩子)
- 如果 parent 的左孩子存在,即 :child < size , 进行以下操作,直到 parent 的左孩子不存在
(1)parent右孩子是否存在,存在找到左右孩子中最小的孩子,让 child 进行标
(2)将parent 与较小的孩子 child 比较,如果: parent 小于较小的孩子 child ,调整结束 否则:交换 parent 与较小的孩子 child ,交换完成之后, parent
中大的元素向下移动,可能导致子树不满足对的性质,因此需要继续向下调整,即parent = child ; child =
parent*2+1; 然后继续 2 。
public void shiftDown(int[] array, int parent) {// child先标记parent的左孩子,因为parent可能右左没有右int child = 2 * parent + 1;int size = array.length;while (child < size) {// 如果右孩子存在,找到左右孩子中较小的孩子,用child进行标记if(child+1 < size && array[child+1] < array[child]){child += 1;}// 如果双亲比其最小的孩子还小,说明该结构已经满足堆的特性了if (array[parent] <= array[child]) {break;}else{// 将双亲与较小的孩子交换int t = array[parent];array[parent] = array[child];array[child] = t;// parent中大的元素往下移动,可能会造成子树不满足堆的性质,因此需要继续向下调整parent = child;child = parent * 2 + 1;}}
}
注意:在调整以parent为根的二叉树时,必须要满足parent的左子树和右子树已经是堆了才可以向下调整。
杂度分析: 最坏的情况 即图示的情况, 从根一路比较到叶子,比较的次数为完全二叉树的高度,即时间复杂度为 O(log N)
2、堆的创建
那对于普通的序列{ 1,5,3,8,7,6 },即根节点的左右子树不满足堆的特性,又该如何调整呢?
需要从倒数第一个非叶子结点开始,依次进行向下调整即可。
public static void createHeap(int[] array) {// 找倒数第一个非叶子节点,从该节点位置开始往前一直到根节点,遇到一个节点,应用向下调整int root = ((array.length-2)>>1);for (; root >= 0; root--) {shiftDown(array, root);}
}
3、建堆的时间复杂度
因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明(时间复杂度本来看的就是
近似值,多几个节点不影响最终结果):
建堆的时间复杂度为O(N)。
四、堆的插入与删除
1、堆的插入
堆的插入总共需要两个步骤:
- 先将元素放入到底层空间中(注意:空间不够时需要扩容)
- 将最后新插入的节点向上调整,直到满足堆的性质
public void shiftUp(int child) {// 找到child的双亲int parent = (child - 1) / 2;while (child > 0) {// 如果双亲比孩子大,parent满足堆的性质,调整结束if (array[parent] > array[child]) {break;} else{// 将双亲与孩子节点进行交换int t = array[parent];array[parent] = array[child];array[child] = t;// 小的元素向下移动,可能到值子树不满足对的性质,因此需要继续向上调增child = parent;parent = (child - 1) / 1;}}
}
2、堆的删除
注意:堆的删除一定删除的是堆顶元素。具体如下:
- 将堆顶元素对堆中最后一个元素交换
- 将堆中有效数据个数减少一个
- 对堆顶元素进行向下调整
五、用堆模拟实现优先级队列
public class MyPriorityQueue {// 演示作用,不再考虑扩容部分的代码private int[] array = new int[100];private int size = 0;public void offer(int e) {array[size++] = e;shiftUp(size - 1);}public int poll() {int oldValue = array[0];array[0] = array[--size];shiftDown(0);return oldValue;}public int peek() {return array[0];}
}
相关文章:

优先级队列(Java )
目录 一、 优先级队列1、概念 二、优先级队列的模拟实现1、堆的概念2、堆的存储方式 三、堆的创建1、堆向下调整2、堆的创建3、建堆的时间复杂度 四、堆的插入与删除1、堆的插入2、堆的删除 五、用堆模拟实现优先级队列 一、 优先级队列 1、概念 优先级队列(Priori…...
大宋咨询如何进行汽车门店6S标准现场检查
随着汽车市场的快速发展,汽车门店的现场管理日益受到关注。6S标准现场检查作为一项重要的评估工具,正在被越来越多的汽车厂商和经销商采用。 6S标准现场检查是指对汽车门店的整理、整顿、清洁、清扫、素养和安全六个方面进行规范和优化,旨在…...
仿牛客网项目---点赞模块的实现
本篇文章介绍一下项目中的点赞模块。 点赞模块是一个通过使用Redis实现的功能模块,它提供了点赞操作的处理逻辑和数据存取功能。通过服务类和控制器类的配合,点赞模块实现了用户对实体的点赞、点赞数量的查询、点赞状态的查询等功能。该模块使用了Redis…...

【AI视野·今日CV 计算机视觉论文速览 第300期】Fri, 1 Mar 2024
AI视野今日CS.CV 计算机视觉论文速览 Fri, 1 Mar 2024 Totally 114 papers 👉上期速览✈更多精彩请移步主页 Daily Computer Vision Papers DistriFusion: Distributed Parallel Inference for High-Resolution Diffusion Models Authors Muyang Li, Tianle Cai, J…...

【单片机学习的准备】
文章目录 前言一、找一个视频是二、画图软件三、装keil5 仿真protues总结 前言 提示:这里可以添加本文要记录的大概内容: 项目需要: 提示:以下是本篇文章正文内容,下面案例可供参考 一、找一个视频是 https://www.b…...

力扣hot100:438.找到字符串中所有字母异位词
26个字符,我复制怎么了?26个字符我比较个数怎么了? 顶多时间复杂度*26 本题用固定窗口大小的滑动窗口每次比较包含26个元素的数组次数,最容易写。 动态窗口大小哈希表存数值(双指针差值)难想难写。 一、动态…...

Kali Linux 2024.1
Kali Linux 2024.1刚刚发布,标志着这个备受欢迎的安全重点Linux发行版在今年的首次重大更新。以其先进的渗透测试和安全审计功能而闻名,它是安全专业人员和爱好者的首选工具。 Kali 2024.1 亮点 本次发布由 Linux 内核 6.6 提供支持,突出了…...
springboot启动加载
目录 使用PostConstruct注解 实现InitializingBean接口 实现CommandLineRunner接口 实现ApplicationRunner接口 使用EventListener注解监听ApplicationReadyEvent事件 应用启动完成之前或者之后,我们需要拿数据库中的一些数据加载到本地缓存中。这些数据一般都…...

基于Java的智能停车场管理系统(Vue.js+SpringBoot)
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容A. 车主端功能B. 停车工作人员功能C. 系统管理员功能1. 停车位模块2. 车辆模块3. 停车记录模块4. IC卡模块5. IC卡挂失模块 三、界面展示3.1 登录注册3.2 车辆模块3.3 停车位模块3.4 停车数据模块3.5 IC卡档案模块3.6 IC卡挂…...
ESD Clamp cell是什么?
ESD CLAMP cell(静电放电钳位单元)是一种专门设计来保护集成电路(IC)免受静电放电(ESD)损害的电路元件。静电放电是在电子设备的组件之间或内部发生的突然电流放电,它可能会损坏电路或降低其性能…...

费率电能表
费率电能表是一种用于测量家庭、商业和工业用电的设备,有效的实现分段计费、分时计费,优化用电效率。费率电能表的产生是为了缓解高峰期的用电负荷,平衡各时间段的用电负荷;根据当地用电负荷曲线情况制定时段费率 在费率电能表中…...

2张图2秒钟3D重建!这款AI工具火爆GitHub,网友:忘掉Sora
只需2张图片,无需测量任何额外数据—— 当当,一个完整的3D小熊就有了: 这个名为DUSt3R的新工具,火得一塌糊涂,才上线没多久就登上GitHub热榜第二。 ▲image 有网友实测,拍两张照片,真的就重建…...
C++高级面试题:请解释 C++ 中的指针和引用之间的区别。
请解释 C 中的指针和引用之间的区别。 在 C 中,指针(Pointers)和引用(References)都是用于处理内存地址的工具,但它们有一些重要的区别: 语法和用法: 指针使用 * 运算符来访问其所…...
Git 配置处理客户端无法正常访问到 github 原网站时,npm 下载依赖包失败的问题
Git 配置处理客户端无法正常访问到 github 原网站时,npm 下载依赖包失败的问题 使用 github 的镜像网站地址或类似的替代产品地址,代替到 npm 拉取依赖包的 git 地址本地Git配置 例如:执行一下命令,则是以https://kgithub.com 替…...

前端爬虫+可视化Demo
爬虫简介 可以把互联网比做成一张 “大网”,爬虫就是在这张大网上不断爬取信息的程序。 爬虫是请求网站并提取数据的自动化程序。 省流:Demo实现前置知识: JS 基础Node 基础 (1)爬虫基本工作流程: 向…...
keepAlive
router c.js const view (name) > () > import(/views/文件夹名/ name) export const c [ {path: /xxx,name: aaa,meta: {title: 哈哈哈,admin: true,keepAlive:true //加这个},component: view(xxx) }, ]adminMain.vue <keep-alive><router-view v-if"…...

蓝桥杯练习题——dp
五部曲(代码随想录) 1.确定 dp 数组以及下标含义 2.确定递推公式 3.确定 dp 数组初始化 4.确定遍历顺序 5.debug 入门题 1.斐波那契数 思路 1.f[i]:第 i 个数的值 2.f[i] f[i - 1] f[i - 2] 3.f[0] 0, f[1] 1 4.顺序遍历 5.记得特判 …...
kotlin基础语法
1.变量 var a:Int 2 //声明类型的可变变量 var b 3 //代码推测可变变量类型 val c 6 //代码推测不可变常量类型 var d:String?null //可为null的String类型的可变变量 latei…...
淘宝天猫商家爬虫工具 电商采集软件使用教程
介绍: 淘宝和天猫是中国最大的电商平台之一,商家在这里销售各种商品。在市场竞争激烈的环境下,了解竞争对手的商品信息和价格变化对于电商运营来说非常重要。本文将介绍如何使用Python编写一个简单的淘宝天猫商家爬虫工具,以获取商…...
建库建表时,最容易忽略的10个细节
大家使用 DolphinDB 创建数据库和表时,有时对于分区列、分区类型和排序列的选择并不十分清晰。如果不加注意,可能导致查询速度变慢、数据丢失或插入错误等问题。合理地设置分区列、排序列和分区类型,有助于加快查询速度,减少内存使…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...

MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...