【优先级队列PriorityQueue】

目录

1,优先级队列

1.1 概念

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

2.1 堆的概念

2.2 堆的存储方式

2.3 堆的创建

2.3.1 堆的向下调整(大根堆)

2.3.2 建堆的时间复杂度​编辑

2.4 堆的插入与删除

2.4.1 堆的插入

2.4.2 堆的删除

3,常用接口介绍

3.1 PriorityQueue的特性

3.2 PriorityQueue常用接口介绍

3.2.1 优先级队列的构造

3.2.2 插入/删除/获取优先级最高的元素

3.2.3 PriorityQueue的大根堆,小根堆转换

3.2.4 PriorityQueue的扩容方式

3.3 oj练习

3.3.1 top-k问题

3.3.2 求一组数据第k小的元素

3.3.3 求一组数据第k大的元素

4,堆的应用

4.1 堆排序        


1,优先级队列

1.1 概念

前面介绍过队列,队列是一种先进先出(FIFO)的数据结构,但有些情况下,操作的数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列,该中场景下,使用队列显然不合适,比如:在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话;初中那会班主任排座位时可能会让成绩好的同学先挑座位。

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

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

JDK1.8中的PriorityQueue底层使用了堆这种数据结构,而堆实际就是在完全二叉树的基础上进行了一些调整。

2.1 堆的概念

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

堆的性质:

堆中某个节点的值总是不大于或不小于其父节点的值

堆总是一棵完全二叉树。

2.2 堆的存储方式

从堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储。

上图,对于非完全二叉树,则不适合使用顺序方式进行存储,因为为了能够还原二叉树,空间中必须要存储空节点,就会导致空间利用率比较低。

如果i为0,则i表示的节点为根节点,否则i节点的双亲节点为 (i - 1)/2

如果2 * i + 1 小于节点个数,则节点i的左孩子下标为2 * i + 1,否则没有左孩子

如果2 * i + 2 小于节点个数,则节点i的右孩子下标为2 * i + 2,否则没有右孩子

2.3 堆的创建

2.3.1 堆的向下调整(大根堆)

因为是以数组存储的,先创建好数组。

此时数组elem中存储的数据为:{27,15,19,18,28,34,65,49,25,37}

从二叉树的角度来看,是这样的:

调整成大根堆:

注意:在调整以parent为根的二叉树时,必须要满足parent的左子树和右子树已经是堆了才可以向下调整。 时间复杂度分析:

最坏的情况即图示的情况,从根一路比较到叶子,比较的次数为完全二叉树的高度,即时间复杂度为O(log以2为底的N)

2.3.2 建堆的时间复杂度

因此:建堆的时间复杂度为O(N)。

2.4 堆的插入与删除

2.4.1 堆的插入

上面已经建立好大根堆了,现在要对他进行插入和删除

比如:我们插入一个80,插入完成以后也要保证他是一个大根堆

因为我们操作的是数组,首先得判断是否已满,满了进行扩容

所以我们就可以通过offer元素来创建大根堆,这是向上调整

创建大根堆的方式可以在一个数组已经给定的情况下,在数组内进行调整(向下调整)

也可以一个一个元素offer进行调整成大根堆(向上调整)

所以向上调整的时间复杂度是很高的

2.4.2 堆的删除

如果说现在是一个大根堆,要删除一个元素,删除的是堆顶元素(优先级队列,优先拿到的堆顶元素),删除一个元素之后,也要保证他还是一个大根堆

删除逻辑:

习题:

3,常用接口介绍

3.1 PriorityQueue的特性

Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,本文主要介绍PriorityQueue。

关于PriorityQueue的使用要注意:

1. 使用时必须导入PriorityQueue所在的包,即:

2. PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出 ClassCastException异常

假如有一个学生类:              没有说明两个Student根据什么比较,所以之前讲过自定义类型,要实现Comperable接口 

3. 不能插入null对象,否则会抛出NullPointerException

4. 没有容量限制,可以插入任意多个元素,其内部可以自动扩容

但是没有容量限制,不是说无线可以往里面放,堆是有大小的

5. 插入和删除元素的时间复杂度为O(log以2为底的N),因为插入以后是向上调整,最多调整的是树的高度,删除也是,第一个和最后一个换,最坏情况0下标一直向下调整,也是树的高度

6. PriorityQueue底层使用了堆数据结构

7. PriorityQueue默认情况下是小堆---即每次获取到的元素都是最小的元素

3.2 PriorityQueue常用接口介绍

3.2.1 优先级队列的构造

那么不能是大根堆吗? 答:可以,后面会讲到

此时呢,我们调用的是不带参数的构造方法,进入源码

源码:

代表只要实现Collection接口的,也就是说Collection接口能引用的对象都能接收

3.2.2 插入/删除/获取优先级最高的元素

3.2.3 PriorityQueue的大根堆,小根堆转换

首先进入offer源码:

上面讲过:我们通过不带参数的构造方法,会给queue分配一个长度大小为11的数组

此时数组长度为11,那么我们第一次放一个数据为10

第二次offer,比如是5

对于上图的CompareTo,只要你插入的元素没有你原来的元素大,就会发生交换!!!

所以和CompareTo的实现有关系

换句话说,如果把if里面的比较改成<=0,那就不一样了

可以看到,这是一个大根堆。

所以,CompareTo实现的方式不一样,就可以控制他是大根堆还是小根堆

现在,我们放的是Integer

进入他的源码:他是实现了Comparable接口的,compareTo自己实现了compare方法

那么回到siftUpComparable

PriorityQueue默认是小根堆,就是因为在调用compareTo的时候比较方式来决定的。

那如果说变成大根堆,我们就可以在自己传入一个比较器

如果说传comparator,只需要把if里面的比较改成<=0,换句话说现在把下面代码变成大根堆

就要自己去传一个比较器

当我们自己实现一个比较器的时候,siftDown方法会走if语句

在这种情况下就是小根堆。

当我们改一下比较器的传值

所以,我们就可以把优先级队列看作是小根堆,也可以看作是大根堆,去控制compare的返回值

3.2.4 PriorityQueue的扩容方式

进入offer源码:

当 i >= 11了,数组长度是11,也就是数组满了,满了以后进行扩容

那我们来看一下这里的扩容,进入grow的源码: 

在JDK1.8中,申请数组的最大长度:Integer.MAX_VALUE(21亿多)- 8 

优先级队列的扩容说明:

如果容量小于64时,是按照oldCapacity的2倍方式扩容的

如果容量大于等于64,是按照oldCapacity的1.5倍方式扩容的

如果容量超过MAX_ARRAY_SIZE,按照MAX_ARRAY_SIZE来进行扩容

3.3 oj练习

3.3.1 top-k问题

TOP-K问题:即求数据集合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。

比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

此时并没有什么问题,代码可以通过。但是不是非常好的解决方案!!!

时间复杂度:

所以这不是真正topK的真正解法!!!

那么如何解决,怎样的解决方式才能实现很小的时间复杂度? 

面试经常问到!!!重点!!!是堆的一个应用!!!

做法:

在这种题里面,往往k是一个很小的数,理论上认为他的时间复杂度为:O(N)

3.3.2 求一组数据第k小的元素

3.3.3 求一组数据第k大的元素

4,堆的应用

4.1 堆排序        

建堆的时间复杂度:O(N),排序的时间复杂度:O(n*logN)

习题:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

香橙派5plus上跑云手机方案二 waydroid

前言 上篇文章香橙派5plus上跑云手机方案一 redroid(带硬件加速)说了怎么跑带GPU加速的redroid方案&#xff0c;这篇说下怎么在香橙派下使用Waydroid。 温馨提示 虽然能运行&#xff0c;但是体验下来只能用软件加速&#xff0c;无法使用GPU加速&#xff0c;所有会很卡。而且…

SpringCloudAlibaba Nacos配置中心与服务发现

目录 1.配置 1.1配置的特点 只读 伴随应用的整个生命周期 多种加载方式 配置需要治理 1.2配置中心 2.Nacos简介 2.1特性 服务发现与服务健康检查 动态配置管理 动态DNS服务 服务和元数据管理 3.服务发现 1.配置 应用程序在启动和运行的时候往往需要读取一些配置信…

AI古风插画视频:成都亚恒丰创教育科技有限公司

AI古风插画视频&#xff1a;科技与传统美学的诗意交融 在数字技术的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;以其惊人的学习能力与创造力&#xff0c;正逐步渗透并重塑着艺术的边界。成都亚恒丰创教育科技有限公司其中&#xff0c;AI古风插画视频作为一股清流&a…

Windows 黑暗模式是什么意思?如何开启它?

随着计算机和移动设备的普及&#xff0c;长时间盯着屏幕已经成为现代人生活和工作的常态。为了减轻眼睛疲劳&#xff0c;并在低光环境中提供更舒适的视觉体验&#xff0c;许多操作系统和应用程序都引入了黑暗模式&#xff08;Dark Mode&#xff09;。 Windows 黑暗模式就是其中…

Xubuntu24.04之图形界面挂载硬盘(二百六十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

双端队列,双指针

思路&#xff1a; 其实很容易想到是双指针或者双端队列。 我们设置一个type表示当前区间已经有了多少种厨师&#xff0c;同时还需要记录区间中每个元素出现的次数&#xff0c;然后比较棘手的是移动问题了&#xff0c;什么时候移动呢&#xff1f; 我们可以发现当区间当队头元…

静脉分割YOLOV8-SEG

静脉分割&#xff0c;YOLOV8*SEG资源-CSDN文库 首先使用YOLOV8-SEG训练&#xff0c;得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;从而摆脱PYTORCH依赖&#xff0c;支持C,PYTHON,ANDROID调用

STM32G474使用HRTIM触发多路ADC采样,通过DMA传输,通过串口打印显示,实现PWM中间时刻采样,避免开关噪声

本工程使用CUBEIDE进行配置以及编译调试&#xff0c;使用的硬件为STM32G474官方开发板NUCLEO-G474RE CUBEIDE配置 HRTIM配置 本章工程使用HRTIM定时器进行ADC的触发&#xff0c;打开主定时器&#xff0c;子定时器A,B,C。&#xff08;本工程未使用到A与C定时器&#xff0c;配置…

项目进度计划、软件部署、调试方案

项目进度计划 项目计划工期:合计3000日历天完成整体项目交付。 软件部署 办公管理系统是一项复杂、长期的系统工程,为保证业务系统能够顺利地进行实施,必须要制定科学、合理、切实可行的实施计划。一方面要从组织上进行落实,成立强有力的项目领导小组和经验丰富的项目实…

【中台建设-Word资料】企业数字化转型之数据中台架构、大数据支撑平台、资源库建设方案

通过中台建设实现企业能力复用&#xff0c;包括能力整合、业务创新、业务和数据闭环、组织模式演进等。 数字能力整合 企业的数字能力一般包括数字化营销、数字化产品、数字化供应链、数字化生产、数字化运营等。企业的数字化能力的充分利用&#xff0c;从而达到可持续发展。数…

2024年上海市安全员C3证证考试题库及上海市安全员C3证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年上海市安全员C3证证考试题库及上海市安全员C3证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试…

一键式创建GTest TDD测试平台

适用于C GTest测试平台搭建。直接上python脚本。 #!/usr/bin/env python3 # -*- coding: utf-8 -*-import argparse import os import platform import subprocess from xml.etree import ElementTree as ETdefault_root_path "d:\\test\\UTtest"class DeveloperTe…

江苏职教高考 计算机 C语言 复习资料

江苏职教高考计算机专业考试内容为 文化课专业课 其中专业课包含&#xff1a; 计算机原理45分 计算机组维45分 计算机网络60分 C语言 6080分 电子电工90分 具体资料可查看链接 链接&#xff1a;https://pan.baidu.com/s/1OXD-zK4V3NsLLDMwfXcTlA?pwd2822 提取码&…

Matlab|基于改进鲸鱼优化算法的微网系统能量优化管理matlab-源码

目录 一、主要内容 二、部分代码 三、运行结果 四、下载链接 一、主要内容 该程序为《基于改进鲸鱼优化算法的微网系统能量优化管理》源码&#xff0c;主要内容如下&#xff1a; 针对包含多种可再生能源的冷热电联供型微网系统的能量优化问题&#xff0c;为了优化其运行过程…

24小时悬停系留照明无人机技术详解

24小时悬停系留照明无人机是一款专门设计用于提供长时间、高效能照明服务的无人机系统。该系统结合了无人机技术与先进的照明设备&#xff0c;通过系留技术实现无人机的稳定悬停&#xff0c;从而提供连续不断的照明服务。该无人机能够在各种环境条件下进行24小时不间断工作&…

请编写函数,判断一字符串是否是回文,若是回文函数返回值为1,否则返回值为0,回文是顺读和倒读都一样的字符串

int gets_arr(char* p) {int i 0;int j strlen(p) - 1;while (i < j && p[i] p[j]){i;j--;}if (i<j){return 0;}else {return 1;}} int main() {printf("请输入一串字符串\n");char arr[100];gets(arr);int ret gets_arr(arr);if (ret 1){printf(…

Linux文件编程(打开/创建写入读取移动光标)

目录 一、如何在Linux下做开发 1.vi编辑器 2.gcc编译工具 3.常用指令 二、文件打开及创建 三、写入文件 四、读取文件 五、文件“光标”位置 一、如何在Linux下做开发 所谓文件编程&#xff0c;就是对文件进行操作&#xff0c;Linux的文件和Windows系统的文件大差不差…

2024浙江外国语学院汉语桥线上项目 “在杭州,看见更好的中国”开班

7月9日上午&#xff0c;由教育部中外语言交流合作中心主办、浙江外国语学院国际商学院承办的2024汉语桥“在杭州&#xff0c;看见更好的中国”线上项目正式启动。项目负责人何骅老师及汉语桥教师团队&#xff0c;与来自越南、缅甸、日本、俄罗斯的100名学员相聚云端&#xff0c…

无法找到模块“@wangeditor/editor-for-vue”的声明文件

vue3项目中使用wangeditor/editor遇到的问题 开发环境不管红线报错正常使用 打包的时候就会报错了 1.安装依赖 pnpm install --save wangeditor/editor wangeditor/editor-for-vuenext 2.遇到的问题 3.解决方法 在src目录下面创建 wangeditor-types.d.ts 文件 代码如下 de…

高速电吹风方案介绍,多档温度风速调节,转速可达105000RPM

高速电吹风是这几年很火的一种电动小家电&#xff0c;能够在较短时间内完成头发干燥&#xff0c;减少对头发的热损伤。可以通过高速电机和风扇来产生高速风流&#xff0c;迅速将头发表面的水分吹干。高速电吹风通常配有多种档位风速和温度可以设置&#xff0c;用户可以根据需要…