当前位置: 首页 > news >正文

优先级队列(堆)

目录

优先级队列

堆的概念

堆的创建

堆的向下调整

堆的插入

完整代码


优先级队列

队列是一种先进先出的数据结构,有些时候操作的数据可能带有优先级,出队列时就需要优先级高的数据先出队列

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

堆的概念

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

 

注意:

  • 已知孩子节点为i,则双亲节点为 (i-1)/2;
  • 已知双亲节点为i,左孩子:2*i+1;右孩子:2*i+2。

堆的创建

堆的向下调整

这里以大根堆为例来讲解堆的向下调整。

题目:对于集合{ 27,15,19,18,28,34,65,49,25,37 }中的数据,如果将其创建成大根堆呢?

 首先我们要定义基本变量,来供使用。因为是对于集合中的数据进行创建大根堆,所以我们可以使用数组来进行。

public class TestHeap {public int[] elem;public int usedSize;public TestHeap(){this.elem = new int[10];}
}

对于如何把数组中的数据放到实现堆的数组里,我们可以通过for循环来进行放置。

注意:这里是有两个数组。

    public void intelem(int[] array){for (int i = 0; i < array.length; i++) {this.elem[i] = array[i];usedSize++;}}

接着我们就要开始创建堆了

    public void createHeap(){for (int parent = (this.usedSize-1-1)/2; parent >= 0 ; parent--) {shifDown(parent, this.usedSize);//每棵树结束时候都给个10,如果接着调整的节点比10//大了,说明这棵树一定调整完了}}

主要的重心在于如何写出shifDown这个方法。

 思路:

  1. 由上面我们能知道 child = parent*2+1。为了确保child的数组不越界,我们要确定循环条件。
  2. 因为是创建大根堆,所以要找到左右子树的最大值同根节点进行比较、交换。
  3. 关于break,这里因为当 前一个节点已经结束了,下面的节点也是结束的状态。
 /**** @param parent 每棵子树调整的起始位置* @param usedSize 判断 每棵子树 什么时候  调整结束*/private void shifDown(int parent, int usedSize) {int child = 2*parent+1;while(child < usedSize){//找到左右子树的最大值if(child+1 < usedSize && elem[child] < elem[child+1]){child++;}if(elem[child] > elem[parent]){swap(elem,child,parent);parent = child;child = 2*parent+1;}else{break;}}}private void swap(int[] elem, int i ,int j){int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}

通过Test测试类和调试,我们能看到大根堆创建成功了。

public class Test {public static void main(String[] args) {int[] array = {27,15,19,18,28,34,65,49,25,37};TestHeap testHeap = new TestHeap();//把array的值赋值给testHeaptestHeap.intelem(array);testHeap.createHeap();
}

创建的堆下图,大根堆。

 

堆的插入

堆的插入总共需要两个步骤:

  1.  先将元素放入到底层空间中(注意:空间不够时需要扩容)
  2. 将最后新插入的节点向上调整,直到满足堆的性质

 其实这和上面的创建大根堆有些类似,但这里用到的是向上调整。

    //插入public void push(int val){if(isFull()){elem = Arrays.copyOf(elem,2*elem.length);}elem[usedSize] = val;sitUp(usedSize);usedSize++;}public boolean isFull(){return elem.length == usedSize;}
}

这里的关键在于向上调整部分代码的编写。

    private void sitUp(int child) {int parent = (child-1)/2;while(parent >= 0){if (elem[parent] < elem[child]){swap(elem,child,parent);child = parent;parent = (child-1)/2;}else{break;}}}

向上调整我们可以先确定孩子节点,最后一棵树的节点位置可以通过 useSize来确定,进而能确定双亲节点。

完整代码

TestHeap类

import java.util.Arrays;public class TestHeap {public int[] elem;public int usedSize;public TestHeap(){this.elem = new int[10];}public void intelem(int[] array){for (int i = 0; i < array.length; i++) {this.elem[i] = array[i];usedSize++;}}public void createHeap(){for (int parent = (this.usedSize-1-1)/2; parent >= 0 ; parent--) {shifDown(parent, this.usedSize);//没棵树结束时候都给个10,如果接着调整的节点比10大了。说明这棵树一定调整完了}}//alt+p+enter 直接生成/**** @param parent 每棵子树调整的起始位置* @param usedSize 判断 每棵子树 什么时候  调整结束*/private void shifDown(int parent, int usedSize) {int child = 2*parent+1;while(child < usedSize){//找到左右子树的最大值if(child+1 < usedSize && elem[child] < elem[child+1]){child++;}if(elem[child] > elem[parent]){swap(elem,child,parent);parent = child;child = 2*parent+1;}else{break;}}}//插入public void push(int val){if(isFull()){elem = Arrays.copyOf(elem,2*elem.length);}elem[usedSize] = val;sitUp(usedSize);usedSize++;}private void swap(int[] elem, int i ,int j){int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}private void sitUp(int child) {int parent = (child-1)/2;while(parent >= 0){if (elem[parent] < elem[child]){swap(elem,child,parent);child = parent;parent = (child-1)/2;}else{break;}}}public boolean isFull(){return elem.length == usedSize;}
}

Test类

public class Test {public static void main(String[] args) {int[] array = {27,15,19,18,28,34,65,49,25,37};TestHeap testHeap = new TestHeap();//把array的值赋值给testHeaptestHeap.intelem(array);testHeap.createHeap();/*for (int i = 0; i < array.length; i++) {testHeap.push(array[i]);}testHeap.push(80);*/}
}

相关文章:

优先级队列(堆)

目录 优先级队列 堆的概念 堆的创建 堆的向下调整 堆的插入 完整代码 优先级队列 队列是一种先进先出的数据结构&#xff0c;有些时候操作的数据可能带有优先级&#xff0c;出队列时就需要优先级高的数据先出队列。 在这种情况下&#xff0c;数据结构应该提供两个最基本…...

帧率和丢帧分析理论

一、丢帧问题概述 应用丢帧通常指的是在应用程序的界面绘制过程中&#xff0c;由于某些原因导致界面绘制的帧率下降&#xff0c;从而造成界面卡顿、动画不流畅等问题。以60Hz刷新率为例子&#xff0c;想要达到每秒60帧&#xff08;即60fps&#xff09;的流畅体验&#xff0c;每…...

solidwork找不到曲面

如果找不到曲面 则右键找到选项卡&#xff0c;选择曲面...

mac安装JetBtains全家桶新版本时报错:Cannot start the IDE

mac安装JetBtains全家桶新版本时报错&#xff1a;Cannot start the IDE 前言报错信息解决方法 前言 作者使用的是Mac电脑&#xff0c;最近想要更新JetBrains相关工具的软件版本&#xff0c;但是在安装时突然报错&#xff0c;导致安装失败&#xff0c;现在将报错信息以及解决方…...

MVCC机制解析:提升数据库并发性能的关键

MVCC机制解析&#xff1a;提升数据库并发性能的关键 MVCC&#xff08;Multi-Version Concurrency Control&#xff09; 多版本并发控制 。 MVCC只在事务隔离级别为读已提交(Read Committed)和可重复读(Repeated Read)下生效。 MVCC是做什么用的 MVCC是为了处理 可重复读 和…...

如何使用Postman搞定带有token认证的接口实战!

现在许多项目都使用jwt来实现用户登录和数据权限&#xff0c;校验过用户的用户名和密码后&#xff0c;会向用户响应一段经过加密的token&#xff0c;在这段token中可能储存了数据权限等&#xff0c;在后期的访问中&#xff0c;需要携带这段token&#xff0c;后台解析这段token才…...

Linux Vim编辑器常用命令

目录 一、命令模式快捷键 二、编辑/输入模式快捷键 三、编辑模式切换到命令模式 四、搜索命令 注&#xff1a;本章内容全部基于Centos7进行操作&#xff0c;查阅本章节内容前请确保您当前所在的Linux系统版本&#xff0c;且具有足够的权限执行操作。 一、命令模式快捷键 二…...

【Android】浅析MVC与MVP

【Android】浅析MVC与MVP 什么是架构&#xff1f; 架构&#xff08;Architecture&#xff09;在软件开发中指的是软件系统的整体设计和结构&#xff0c;它描述了系统的高层组织方式&#xff0c;包括系统中各个组件之间的关系、依赖、交互方式&#xff0c;以及这些组件如何协同…...

spark 面试题

spark 面试题 1、spark 任务如何解决第三方依赖 比如机器学习的包&#xff0c;需要在本地安装&#xff1f;--py-files 添加 py、zip、egg 文件不需要在各个节点安装 2、spark 数据倾斜怎么解决 spark 中数据倾斜指的是 shuffle 过程中出现的数据倾斜&#xff0c;主要是由于…...

青柠视频云——如何开启HTTPS服务?

前言 由于青柠视频云的语音对讲会使用到HTTPS服务&#xff0c;这里我们说一下如何申请证书以及如何在实战中部署并且配置使用。 一、证书申请 1、进入控制台 我们拿阿里云的免费个人证书为例&#xff0c;首先登录阿里云&#xff0c;在控制台找到数字证书管理服务&#xff0c;进…...

2016年国赛高教杯数学建模A题系泊系统的设计解题全过程文档及程序

2016年国赛高教杯数学建模 A题 系泊系统的设计 近浅海观测网的传输节点由浮标系统、系泊系统和水声通讯系统组成&#xff08;如图1所示&#xff09;。某型传输节点的浮标系统可简化为底面直径2m、高2m的圆柱体&#xff0c;浮标的质量为1000kg。系泊系统由钢管、钢桶、重物球、…...

vue-使用refs取值,打印出来是个数组??

背景&#xff1a; 经常使用$refs去获取组件实例&#xff0c;一般都是拿到实例对象&#xff0c;这次去取值的时候发现&#xff0c;拿到的竟然是个数组。 原因&#xff1a; 这是vue的特性,自动把v-for里面的ref展开成数组的形式&#xff0c;哪怕你的ref名字是唯一的&#xff01…...

微服务_入门1

文章目录 一、 认识微服务二、 微服务演变2.1、 单体架构2.2、 分布式架构2.3、 微服务2.4、 微服务方案对比 三、 注册中心3.1、 Eureka3.2、 Nacos3.2.1、服务分级存储模型3.2.2、权重配置3.2.3、环境隔离 一、 认识微服务 二、 微服务演变 随着互联网行业的发展&#xff0c;…...

【学习资料】袋中共36个球,红白黑格12个,问能一次抽到3个红4个白5个黑的概率是多少?

1、公式计算 1.1 题目1 袋中共 36 36 36个球&#xff0c; 红 \fcolorbox{red}{#FADADE}{\color{red}{红}} 红​ 白 \fcolorbox{white}{#808080}{\color{white}{白}} 白​ 黑 \fcolorbox{#808080}{#0D0D0D}{\color{#808080}{黑}} 黑​各 12 12 12个&#xff0c;问能一次抽到 3…...

@PathVariable,@RequestParam,@RequestBody注解,springboot与前端请求之间的数据类型转换

前端数据与springboot java数据类型转换 springboot&mybatis中数组和字符串数据类型的转换-CSDN博客中曾经提到&#xff0c;在Spring Boot中&#xff0c;通过URL传参、payload中的key-value形式或json形式&#xff0c;将前端数据以字符串格式发送到后端&#xff0c;后端We…...

在Python中优雅地打开和操作RDS

在Python中优雅地打开和操作RDS 随着数据存储需求的不断增长&#xff0c;关系数据库服务&#xff08;Relational Database Service, RDS&#xff09;成为了许多企业首选的数据存储方式。那么&#xff0c;在Python中如何轻松地与RDS进行交互呢&#xff1f;以下是一份详尽的指南…...

.whl文件下载及pip安装

以安装torch_sparse库为例 一、找到自己需要的版本&#xff0c;点击下载。 去GitHub的pyg-team主页中找到pytorch-geometric包。网址如下&#xff1a; pyg-team/pytorch_geometric​github.com/pyg-team/pytorch_geometric 然后点击如图中Additional Libraries位置的here&am…...

望繁信科技受邀出席ACS2023,为汽车行业数智化护航添翼

2023年5月25-26日&#xff0c;ACS2023第七届中国汽车数字科技峰会在上海成功举行。此次峰会汇聚了众多汽车领域的顶级专家、产业链代表及企业高管&#xff0c;共同探讨当今汽车产业的转型与未来发展趋势。 作为唯一受邀的流程挖掘厂商代表&#xff0c;望繁信科技携最新行业优势…...

基于 C语言的 Modbus RTU CRC 校验程序

一、CRC校验原理 Modbus RTU是一种常用于工业设备通信的协议&#xff0c;它基于串行通信&#xff0c;如RS-232或RS-485。在Modbus RTU中&#xff0c;CRC&#xff08;循环冗余校验&#xff09;是一种常用的错误检测机制&#xff0c;用于确保数据在传输过程中的完整性和准确性。 …...

基于微信小程序的剧本杀游玩一体化平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的剧…...

AMD或Intel上编译出来的程序,可以跑在海光上吗?

在上一篇博文《海光处理器与AMD Zen1的指令差异-CSDN博客》中发现&#xff0c;海光相比AMD&#xff0c;缺失了一些指令集。 那么在AMD或Intel上编译出来的程序&#xff0c;可以跑在海光上吗&#xff1f; 这个问题的关键&#xff0c;在于编译器默认使用哪些指令来编译程序。以Ce…...

ChatGPT 4o 使用指南 (9月更新)

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…...

微信getUserProfile不弹出授权框

当我们在微信小程序开发工具中想要使用getUserProfile来获取个人信息的时候&#xff0c;会发现不弹出授权框&#xff0c;这是什么原因呢&#xff1f; 早在2022年的小程序官方公告中就已经明确给出了小程序用户头像昵称获取规则调整公告 因此如果还想继续使用getUserProfile的弹…...

iostat 命令:系统状态监控

一、命令简介 ​iostat ​命令用于报告系统中 CPU、磁盘、tty 设备和 CPU 利用率统计信息。 ‍ 需安装 sysstat ​软件包&#xff0c;该软件包提供了一组工具&#xff0c;包括 iostat​、sar​、mpstat ​等&#xff0c;用于系统性能监控和报告。 ‍ 二、命令参数 iostat…...

从底层原理上解释 ClickHouse 的索引

ClickHouse 是一款高性能的列式数据库&#xff0c;它通过列式存储、稀疏索引、MergeTree 引擎等技术实现了极高的查询效率和吞吐量。索引是数据库中提高查询效率的关键机制之一。为了深入了解 ClickHouse 中的索引实现机制&#xff0c;我们将从底层原理、关键数据结构以及 Clic…...

9.20-使用k8s部署wordpress项目

部署wordpress项目 部署mariadb # 启动docker进程systemctl start docker​# 拉取三个镜像​docker pull nginx:alpinedocker pull wordpress:latestdocker pull mariadb:latest​# 保存三个镜像​cddocker save -o wordpress.tar wordpress:latestdocker save -o mariadb.tar…...

OSPFv3协议几类LSA介绍

OSPFv3协议介绍 与OSPFv2相比&#xff0c;OSPFv3在工作机制上与OSPFv2基本相同&#xff1b;但为了支持IPv6地址格式&#xff0c;OSPFv3对OSPFv2做了一些改动。OSPFv3基于OSPFv2基本原理增强&#xff0c;是一个独立的路由协议&#xff08;v3不兼容v2&#xff09;协议号仍然是89…...

煤矿智慧矿井数据集 (1.煤矿采掘工作面智能分析数据集2.煤矿井下钻场智能分析数据集 )

智慧矿井智能分析数据集 数据1&#xff1a;数据1包含煤矿采掘工作面工人安全帽检测&#xff0c;工人行为检测&#xff08;行走&#xff0c;站立&#xff0c;坐&#xff0c;操作&#xff0c;弯腰&#xff0c;靠&#xff0c;摔&#xff0c;爬&#xff09;&#xff0c;液压支撑防护…...

举例说明协方差的数学公式计算步骤以及皮尔逊相关系数数学公式的计算步骤

例子&#xff1a;协方差的计算步骤 协方差是用于衡量两个随机变量之间的线性相关性的统计量。它表示两个变量如何一起变化。如果协方差为正&#xff0c;表示两个变量倾向于同方向变化&#xff1b;如果为负&#xff0c;表示它们倾向于反方向变化。 下面我们将通过一个具体的例…...

2024/9/16论文赏析(均为1区或顶刊

Labeled-to-Unlabeled Distribution Alignment for Partially-Supervised Multi-Organ Medical Image Segmentation 代码链接&#xff1a;GitHub - xjiangmed/LTUDA 论文链接&#xff1a;Labeled-to-Unlabeled Distribution Alignment for Partially-Supervised Multi-Organ …...