数据结构 - 优先级队列(堆)
文章目录
- 前言
- 1.介绍优先级队列
- 2. 认识堆
- 3. 实现优先级队列
- 3.1 了解优先级队列的构造方法:
- 3.2 使用优先级队列解决问题:
- 总结
前言
本篇PriorityQueue优先级队列的介绍其底层是堆,关于堆的认识,使用优先级队列能解决的一些问题;如有错误,请在评论区指正,让我们一起交流,共同进步!
本文开始
1.介绍优先级队列
优先级队列:它的底层是一种堆的数据结构,它以顺序结构存储,是一个一维数组;
既然底层是堆,就来了解一下!
2. 认识堆
认识堆的特点:有两种堆类型
① 小根堆:父节点小于左右孩子节点,不能保证左右孩子谁大; =》使用优先级队列就创建了小根堆,想要创建大根堆需要自己给比较器(根据自定义规则比较,用于节点交换);
② 大根堆:父节点大于左右孩子节点,不能保证左右孩子谁大;
③ 堆还是完全二叉树:可以使用顺序存储;非完全二叉树存储,为了还原二叉树还需要存储空节点,浪费空间 - 》堆为什么可以顺序存储的原有;
代码实现小根堆:
向下调整(父节点向下走):从最后一颗子树开始,父节点与子节点比较大小是否交换,直到不用比较就确定了小根堆;
/*** 建堆的时间复杂度:* O(n)*/
//求出最后一个父节点,因为是顺序存储的-1就是下一颗树的父节点public void createHeap(int[] array) {for (int parent = (usedSize - 1) / 2; parent >= 0; parent--) {//获取最后一个子树父节点,usedSize记录数组中存储的个数//传递父节点和孩子节点最大的范围shiftDown(parent,usedSize);}}/*** root 是每棵子树的根节点的下标* len 是每棵子树调整结束的结束条件* 向下调整的时间复杂度:O(logn) ;最坏换树的高度*/private void shiftDown(int root,int len) {//向下调整需要每个子树的父节点int child = 2 * root + 1;//求出左孩子节点位置while (child < len) {//获取孩子节点最大值下标//防止右孩子下标越界,需要判断if(child + 1 < len && elem[child] < elem[child + 1]) {child++;}//比较父子节点大小if(elem[child] > elem[root]) {swap(elem,child,root);//调整父子节点下标位置child = root;root = 2 * child + 1;//再次获取左孩子节点下标}else {//父节点大于子节点直接跳出break;}}}//交换函数private void swap(int[] elem, int child, int root) {int tmp = elem[child];elem[child] = elem[root];elem[root] = tmp;}
代码实现大根堆
向上调整(孩子节点向上走):
private void shiftUp(int child) {//求出它的父节点下标int parent = (child - 1) / 2;//child==0最后一个节点不用比较while (child > 0) {//比较父子节点大小if(elem[child] > elem[parent]) {//交换swap(elem,child,parent);//移动父子节点下标,可能不止移动一次(子节点向上)child = parent;parent = (child - 1) / 2;//获得更上一级的父节点下标}else {//父节点小于子节点直接跳出break;}}
}
3. 实现优先级队列
了解大根堆,小根堆就可以实现优先级队列!
代码实现优先级队列(以大根堆为例):
public class PriorityQueue {public int[] elem;public int usedSize;public PriorityQueue() {int[] elem = new int[10];}//交换函数private void swap(int[] elem, int child, int root) {int tmp = elem[child];elem[child] = elem[root];elem[root] = tmp;}/*** 入队:仍然要保持是大根堆*/public void push(int val) {//插入if(isFull()) {//扩增Arrays.copyOf(elem,2*elem.length);return;}//没满就在最后位置插入elem[usedSize] = val;//向上调整即可shiftUp(usedSize);usedSize++;}public boolean isFull() {return usedSize == elem.length;}/*** 出队删除:每次删除的都是优先级高的元素* 仍然要保持是大根堆*/public void pollHeap() {if(isEmpty()) {return;}//交换首尾int end = usedSize - 1;swap(elem,0,end);//向下调整范围需要-1,因为删除了一个元素shiftDown(0,--usedSize);}
//判断是否为空public boolean isEmpty() {return usedSize == 0;}/*** 获取堆顶元素*/public int peekHeap() {if(isEmpty()) {return -1;}return elem[0];}
}
3.1 了解优先级队列的构造方法:
① 无参构造:默认大小11
② 有一个整形参数的构造:
③ 两个参数(整形,比较规则)的构造:
3.2 使用优先级队列解决问题:
1.top-k问题:
例如取前k个最小 / 最大的值;
2.堆排序
①升序(1,2,3…):大根堆
使用原因:大根堆堆顶元素一定最大的,将堆顶元素与堆末尾元素交换,再向下调整,重新得到大根堆;这样每次都会把最大的放到最后,再次到堆顶的时候,堆顶后面的元素已经有序了,依次弹出即可;
②降序(4,3,2…):小根堆
使用原有:小根堆堆顶元素一定最小的,将堆顶元素与堆末尾元素交换,再向下调整,重新得小根堆;这样每次都会把最小的放到最后,再次到堆顶的时候,堆顶后面的元素已经降序有序了,依次弹出即可;
总结
✨✨✨各位读友,本篇分享到内容如果对你有帮助给个👍赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!
相关文章:
数据结构 - 优先级队列(堆)
文章目录前言1.介绍优先级队列2. 认识堆3. 实现优先级队列3.1 了解优先级队列的构造方法:3.2 使用优先级队列解决问题:总结前言 本篇PriorityQueue优先级队列的介绍其底层是堆,关于堆的认识,使用优先级队列能解决的一些问题&…...
PDF内容提取器:ByteScout PDF Extractor SDK Crack
ByteScout PDF Extractor SDK – 用于 PDF 到 JSON、PDF 到 Excel、CSV、XML、从 .NET 和 ASP.NET 从 PDF 中提取文本的 PDF 提取器库 ByteScout PDF Extractor SDK – 用于 PDF 到 JSON、PDF 到 Excel、CSV、XML、从 .NET 和 ASP.NET 从 PDF 中提取文本的 PDF 提取器库 …...
字母板上的路径[提取公共代码,提高复用率]
提取公共代码前言一、字母版上的路径二、贪心1、idea2、go3、代码不断拆分复用的过程总结参考文献前言 写代码,在提高效率的同时,要方便人看,这个人包括自己。大函数要拆分成一些小函数,让每个函数的宏观目的和步骤都显得清晰&am…...
c# winform错误大全
c# winform 错误大全为了实现安装包安装完成后,启动程序。System.BadImageFormatException: 未能加载文件或程序集“file:///C:\xxxxxxxxx\xxxxxxx.exe”或它的某一个依赖项。生成此程序集的运行时比当前加载的运行时新,无法加载此程The version of the …...
AI_News周刊:第一期
2023.02.06—2023.02.12 关于ChatGPT的前言: 在去年年末,OpenAI的ChatGPT在技术圈已经火了一次,随着上周它的二次出圈,ChatGPT算得上是人工智能领域的一颗明星,它在聊天机器人领域有着不可忽视的影响力。其准确、快速…...
搭建mysql主从复制
前言: 👏 作者简介:我是笑霸final,一名热爱技术的在校学生。 📝 个人主页:个人主页1 || 笑霸final的主页2 📕 系列专栏:数据库 📧 如果文章知识点有错误的地方࿰…...
内存溢出、内存泄露的概述及常见情形
内存溢出(OutofMemoryError) 简述 java doc 中对 Out Of Memory Error 的解释是,没有空闲内存,并且垃圾收集器也无法提供更多内存。 JVM 提供的内存管理机制和自动垃圾回收极大的解放了用户对于内存的管理,由于 GC&…...
Linux 中断实验
目录 一、Linux 中断简介 上半部与下半部 二、添加设备树 三、编写驱动 1、定义宏 2、编写一个key结构体 3、imx6uirq设备添加成员 编辑4、按键中断处理函数 5、按键初始化 6、在驱动入口添加初始化 7、 驱动出口函数 代码如下 四、利用定时器进行消抖处理 1、添…...
【c++】指针
文章目录指针的定义和使用指针所占的内存空间空指针野指针const修饰指针指针和数组指针和函数指针、数组、函数案例:冒泡排序指针的定义和使用 指针定义的语法:数据类型 * 指针变量名 使用指针: 可以通过解引用的方式来找到指针指向的内存&…...
别具一格的婚礼,VR全景+婚礼的优势展现在哪里?
随着90后、95后逐渐步入结婚的主力军中,如何策划一场别具一格的婚礼是许多年轻人所头疼的,那么今年我们就可以玩点新潮的,VR婚礼或许是个不错的选择。 VR全景婚礼就是通过全景摄像机对婚礼进行记录,不但可以帮助新人捕捉婚礼的精彩…...
【GD32F427开发板试用】5. SPI驱动TFTLCD屏幕
本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:hehung 之前发帖 【GD32F427开发板试用】1. 串口实现scanf输入控制LED 【GD32F427开发板试用】2. RT-Thread标准版移植 【GD32F427开发板试用…...
测试2年还拿实习生的薪资打发我,你后悔去吧····
20年7月大学毕业,学的计算机科学专业。因为考研之后,秋招结束了。没什么更多的岗位选择,就想找个工作先干着,然后亲戚在一家大厂公司上班说要招测试,所以就来做测试了。 虽然都是属于计算机大类,但自己专业…...
面向对象程序(C++)设计基础
一、类&对象C 在 C 语言的基础上增加了面向对象编程,C 支持面向对象程序设计。类是 C 的核心特性,通常被称为用户定义的类型。类提供了对象的蓝图,所以基本上,对象是根据类来创建的。声明类的对象,就像声明基本类型…...
conda安装nodejs版本过低解决方法
conda命令直接安装nodejs时,可能会由于镜像源中nodejs版本过低导致没法安装高本版的nodejs,导致无法jupyterlab使用一些扩展插件。 解决方法如下:(windows环境下直接按提示下载版本安装就行,此处只介绍linux环境的解决…...
前端工程师leetcode算法面试必备-二分搜索算法(下)索算法(下)
一、287. 寻找重复数 给定一个包含 n 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。 1、HashMap 在没有其它附加条件的情况下&…...
使用Autowired为什么会被IDEA警告,应该怎么修改最佳
问题原因 关于这个问题,其实答案相对统一,实际上用大白话说起来也容易理解。 初始化问题 先看一下Java初始化类的顺序:父类的静态字段 > 父类静态代码块 > 子类静态字段 > 子类静态代码块 > 父类成员变量 > 父类构造代码块 &…...
面向对象(中)
面向对象(中) 一、 面向对象之继承性 继承性的好处 减少代码的冗余,提高了代码的复用性。 便于功能的扩展。 为多态性的使用,提供了前提。 继承性的格式 class A extends B{} A:子类、派生类、subclass B:…...
【云原生】promehtheus整合grafana实现可视化监控实战
文章目录前言一. 实验环境二. 安装grafana2.1 grafana的介绍2.2 为什么选择grafana?2.3 grafana下载及安装三. 网页端配置grafana3.1 浏览器访问grafana网页3.2 使用grafana 获取prometheus的数据源3.3 grafana导入prometheus模板总结前言 大家好,又见面…...
Linux 内核定时器实验
目录 一、内核时间管理简介 二、内核定时器简介 三、驱动编写 1、修改makefile 2、添加定义 3、初始化led函数 4、添加调用 5、初始化定时器与定时器处理函数 这部分代码如下 四、ioctl函数 五、内核添加unlocked_ioctl 函数 1、添加设备操作集unlocked_ioctl成员 2…...
喜欢大屏电视?那就选择酷开系统,实现智能生活享受
随着科技的发展和我们生活水平的提高,越来越多的消费者开始认可并习惯使用各种高质量的科技产品,比如喜欢玩游戏的消费者,他们往往会追求流畅性更强、刷新率更快的大显示屏,以此获得更真实刺激的游戏体验,而喜欢追剧的…...
OpenClaw新手必看:nanobot镜像的20个实用命令合集
OpenClaw新手必看:nanobot镜像的20个实用命令合集 1. 初识nanobot镜像 第一次接触OpenClaw的nanobot镜像时,我被它的轻量化设计所吸引。这个基于vllm部署的Qwen3-4B-Instruct-2507模型镜像,不仅体积小巧,还集成了chainlit推理界…...
ESP32/ESP8266嵌入式NVS数据库C++封装库
1. 项目概述NVSDatabase 是一个面向 ESP-IDF 生态的 C 封装库,其核心目标是为 ESP32 和 ESP8266 平台提供类型安全、接口清晰、工程友好的非易失性存储(Non-Volatile Storage, NVS)访问能力。该库并非对底层 NVS API 的简单 C 风格包装&#…...
**发散创新:用Go语言构建高性能服务网格代理——从零实现Sidecar模式**在微服务架构日益普及的今天,
发散创新:用Go语言构建高性能服务网格代理——从零实现Sidecar模式 在微服务架构日益普及的今天,服务网格(Service Mesh) 已成为保障流量治理、安全认证与可观测性的核心基础设施。传统基于API网关的集中式控制方式已难以满足动态…...
测试覆盖率99.5%的终极革命:claude-code-sub-agents如何重新定义自动化测试
测试覆盖率99.5%的终极革命:claude-code-sub-agents如何重新定义自动化测试 【免费下载链接】claude-code-sub-agents Collection of specialized AI subagents for Claude Code for personal use (full-stack development). 项目地址: https://gitcode.com/gh_mi…...
从物流仓库到游戏背包:三维装箱问题(3D-BPP)如何影响你的日常生活?
从物流仓库到游戏背包:三维装箱问题如何塑造我们的数字生活 清晨打开手机里的策略游戏,你发现背包格子又不够用了——那些珍贵的装备和药水总是无法完美摆放;周末搬家时,面对满屋的家具和纸箱,你突然意识到小货车可能装…...
毕设程序java基于的动漫分析与交流平台 基于Spring Boot的二次元文化社区与作品分享系统 Java驱动的ACG内容聚合与互动服务平台
毕设程序java基于的动漫分析与交流平台31sl5luf(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着互联网技术的飞速发展和Z世代文化消费的崛起,动漫产业已从边缘亚文…...
【调优】Openclaw高阶调优指南之配置篇
适配openclaw 2026.3.23+版本,收录于 养龙虾专栏 本文的配置调优主要包含如下内容,优化调整的地方均有截图,无需担心命令无效: 标题 配置优化内容 主要内容概要 一、OpenClaw配置体系概述 1. 配置文件结构与位置 介绍 openclaw.json 的路径及 JSON5 格式特性 2. 配置生效机…...
基于Ai Coding,20天完成一个基于大模型的医学分析系统:Ai体征分析助手
我是一名长期使用C#开发后台服务与数据库的开发者,在短短20天内,独立完成一个跨前后端、贴合医疗健康场景分析的完整系统(Ai体征分析助手)是未曾想过的。得益于AI Coding工具的深度实践与应用和医疗领域大模型的应用,让…...
OpenCode终极指南:开源AI编程助手如何重塑你的开发体验
OpenCode终极指南:开源AI编程助手如何重塑你的开发体验 【免费下载链接】opencode 一个专为终端打造的开源AI编程助手,模型灵活可选,可远程驱动。 项目地址: https://gitcode.com/GitHub_Trending/openc/opencode 你是否厌倦了在多个A…...
Audio Flamingo 3:打破模态壁垒的音频智能突破性技术解析
Audio Flamingo 3:打破模态壁垒的音频智能突破性技术解析 【免费下载链接】audio-flamingo-3 项目地址: https://ai.gitcode.com/hf_mirrors/nvidia/audio-flamingo-3 在音频AI领域面临"模态孤岛"困境与长音频理解需求激增的双重挑战下࿰…...


