优先级队列(堆)的实现

1.什么是优先级队列

队列是一种先进先出(FIFO)的数据结构,但有些情况下,操作的数据可能带有优先级,一般出队
列时,可能需要优先级高的元素先出队列
,该中场景下,使用队列显然不合适,比如:在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话。
在这种情况下,数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue)。
 

2. 优先级队列模拟实现

堆实际就是在完全二叉树的基础上进行了一些调整。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

小根堆:                                                                            大根堆:

                  
堆的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。

 

 1)堆的向下调整

 以集合{ 27,15,19,18,28,34,65,49,25,37 }中的数据为例

1. 让parent标记需要调整的节点,child标记parent的左孩子(注意:parent如果有孩子一定先是有左孩子)

2. 如果parent的左孩子存在,即:child < end, 进行以下操作,直到parent的左孩子不存在

      parent右孩子是否存在,存在找到左右孩子中最小的孩子,让child进行标

      将parent与较小的孩子child比较,如果:

              parent小于较小的孩子child,调整结束;

              否则:交换parent与较小的孩子child,交换完成之后,parent中大的元素向下移动,可能导致子树不满足堆的性质,因此需要继续向下调整,即parent = child;child = parent*2+1; 然后继续2

 

   /**** @param parent 是每棵子树的根节点的下标* @param end  是每棵子树调整结束的结束条件* 向下调整的时间复杂度:O(logn)*/private void shiftDown(int parent,int end) {int child=2*parent+1;while(child<end){if(child+1<usedSize && elem[child]<elem[child+1]){child++;}if(elem[child]>elem[parent]){swap(child,parent);parent=child;child=2*parent+1;}else {break;}}}private void swap(int i,int j) {int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}

 

2)建堆 

  public void createBigHeap(int[] array) {for(int parent=(usedSize-1-1)/2;parent>=0;parent--){shiftDown(parent,usedSize);}}

 

3)堆的插入

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

 

 /*** 堆的删除:每次删除的都是优先级高的元素* 仍然要保持是大根堆*/public int poll() {if(isEmpty()){return -1;}int tmp=elem[0];swap(0,usedSize-1);usedSize--;shiftDown(0,usedSize);return tmp;}public boolean isEmpty() {return usedSize==0;}

 

4)堆的删除

  1.  将堆顶元素对堆中最后一个元素交换
  2.  将堆中有效数据个数减少一个
  3.  对堆顶元素进行向下调整

 

    /*** 堆的插入:仍然要保持是大根堆* @param val*/public void offer(int val) {if(isFull()){this.elem= Arrays.copyOf(elem,2*elem.length);}elem[usedSize]=val;usedSize++;shiftUp(usedSize-1);}private void shiftUp(int child) {int parent=(child-1)/2;while(child<0){if(elem[child]>elem[parent]){swap(child,parent);child=parent;parent=(child-1)/2;}else {break;}}}

 

 全部代码: 

import java.util.Arrays;public class PriorityQueue {public int[] elem;public int usedSize;//数组已使用的空间public PriorityQueue() {this.elem=new int[10];}//初始化elem数组public void initElem(int[] array){for(int i=0;i<elem.length;i++){elem[i]=array[i];usedSize++;}}/*** 建堆的时间复杂度:O(N)** @param array*/public void createBigHeap(int[] array) {for(int parent=(usedSize-1-1)/2;parent>=0;parent--){shiftDown(parent,usedSize);}}/**** @param parent 是每棵子树的根节点的下标* @param end  是每棵子树调整结束的结束条件* 向下调整的时间复杂度:O(logn)*/private void shiftDown(int parent,int end) {int child=2*parent+1;while(child<end){if(child+1<usedSize && elem[child]<elem[child+1]){child++;}if(elem[child]>elem[parent]){swap(child,parent);parent=child;child=2*parent+1;}else {break;}}}private void swap(int i,int j) {int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}/*** 堆的插入:插入完后仍然要保持是大根堆* @param val*/public void offer(int val) {if(isFull()){this.elem= Arrays.copyOf(elem,2*elem.length);}elem[usedSize]=val;usedSize++;shiftUp(usedSize-1);}private void shiftUp(int child) {int parent=(child-1)/2;while(child<0){if(elem[child]>elem[parent]){swap(child,parent);child=parent;parent=(child-1)/2;}else {break;}}}public boolean isFull() {return usedSize==elem.length;}/*** 堆的删除:每次删除的都是优先级高的元素* 仍然要保持是大根堆*/public int poll() {if(isEmpty()){return -1;}int tmp=elem[0];swap(0,usedSize-1);usedSize--;shiftDown(0,usedSize);return tmp;}public boolean isEmpty() {return usedSize==0;}/*** 获取堆顶元素* @return*/public int peek (){return elem[0];}
}

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

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

相关文章

堆的实现

前言&#xff1a;本文讲述堆实现的几个难点&#xff0c;注意本文主要是以实现为主&#xff0c;建议有些基本概念认识的人阅读。 目录 1.堆 2.堆的实现 堆结构的定义&#xff1a; 要实现的接口&#xff1a; 接口的实现&#xff1a; 堆的初始化和销毁&#xff1a; 向堆中插…

人工智能-YOLOv10-行人和车辆检测-yolo改进测距测速代码和原理

YOLOv10: 实时端到端目标检测技术的全新突破 YOLOv10代表了实时目标检测领域的重大进展&#xff0c;是YOLO系列模型的最新迭代&#xff0c;专为追求极致效率与精度平衡的应用场景设计。此项目由北京大学机器智能研究组&#xff08;THU-MIG&#xff09;的Ao Wang、Hui Chen、Li…

02_前端三大件HTML

文章目录 HTML用于网页结构搭建1. 标签2. 客户端服务器交互流程3. 专业词汇4. html语法细节5. 安装VSCODE安装插件6. Live Server插件使用7. 标题&段落&换行&列表8. 超链接标签使用9. 图片10. 表格的写法11. 表单标签*(重点)12. 下拉框13. 页面布局标签14. 块元素和…

RT-Thread Env开发探索——以HC-SR04超声波传感器为例

RT-Thread Env开发探索——以HC-SR04超声波传感器为例 0.前言一、BSP优化1.修改芯片功能配置2.修改RTT配置菜单 二、软件包加载1.外设配置2.驱动框架配置3.软件包配置 三、编译及运行四、源码分析五、总结 参考文章&#xff1a;RT Thread Env CLion环境搭建 0.前言 对比使用R…

mac下安装airflow

背景&#xff1a;因为用的是Mac的M芯片的电脑&#xff0c;安装很多东西都经常报错&#xff0c;最近在研究怎么把大数据集群上的crontab下的任务都配置到一个可视化工具中&#xff0c;发现airflow好像是个不错的选择&#xff0c;然后就研究怎么先安装使用起来&#xff0c;后面再…

部署LAMP平台

目录 一、LAMP简介与概述 1.1 各组件作用 1.2 LAMP平台搭建时各组件安装顺序 1.3 httpd服务的目录结构 1.4 httpd.conf配置文件 二、编译安装Apache httpd服务 2.1 关闭防火墙&#xff0c;将安装Apache所需软件包传到/opt目录下 2.2 安装环境依赖包 ​2.3 配置软件模块…

基于RK3588的AI边缘计算网关设计

随着物联网和人工智能技术的飞速发展&#xff0c;边缘计算逐渐成为数据处理和分析的重要趋势。RK3588作为一款高性能的处理器&#xff0c;具备强大的计算能力和丰富的接口&#xff0c;为构建AI边缘计算网关提供了有力的支持。本文将介绍基于RK3588的AI边缘计算网关设计&#xf…

【Redis】 关于 Redis 哈希类型

文章目录 &#x1f343;前言&#x1f38b;命令介绍&#x1f6a9;hset&#x1f6a9;hget&#x1f6a9;hexists&#x1f6a9;hdel&#x1f6a9;hkeys&#x1f6a9;hvals&#x1f6a9;hgetall&#x1f6a9;hmget&#x1f6a9;hlen&#x1f6a9;hsetnx&#x1f6a9;hincrby&#x1…

弹性盒子布局,flex布局

弹性盒子布局&#xff08;Flexbox&#xff09;是CSS3引入的一种新的布局模式&#xff0c;它提供了一种更加有效的方式来设计、布局和对齐容器中的项目&#xff0c;即使容器的大小动态改变或者项目的数量未知。 弹性盒子布局的主要特点是能够轻松地在不同的屏幕大小和设备上实现…

使用VCPKG编译并使用Qt5

一、背景 Qt就不介绍了。VCPKG可以看这里VCPKG资料记录_vcpkg boost 多久-CSDN博客 为什么搞Qt5而不是Qt6&#xff1f;因为Qt5比较稳定吧。而且我公司也是用的Qt5。 为什么要自己编译而不是去下载Qt5&#xff1f; 第一&#xff0c;因为Qt5在Qt在线安装版本只提供到Qt5.15.2&…

【CTF Web】CTFShow web3 Writeup(SQL注入+PHP+UNION注入)

web3 1 管理员被狠狠的教育了&#xff0c;所以决定好好修复一番。这次没问题了。 解法 注意到&#xff1a; <!-- flag in id 1000 -->但是拦截很多种字符。 if(preg_match("/or|\-|\\|\*|\<|\>|\!|x|hex|\/i",$id)){die("id error"); }使用…

Linux驱动设备导论(1)

最近本人在学习Linux驱动&#xff0c;本系列教程是本人在一边学习&#xff0c;一边总结的系列教程&#xff0c;希望能够给很多刚学驱动小伙伴一些总结。 1.Linux设备分类 驱动针对的对象是存储器和外设&#xff0c;不是针对CPU&#xff0c;可以分为以下三大类&#xff1a; 1.…

『Stable Diffusion 』AI绘画,不会写提示词怎么办?

提示词 有没有想过&#xff0c;为什么你用 SD 生成的猫是长这样的。 而其他人可以生成这样的猫。 虽然生成的都是猫&#xff0c;但猫与猫之间还是有差距的。 如果你的提示词只是“cat”&#xff0c;那大概率就会出现本文第一张图的那个效果。而如果你加上一些形容词&#xff…

C#应用的用户配置窗体方案 - 开源研究系列文章

这次继续整理以前的代码。本着软件模块化的原理&#xff0c;这次笔者对软件中的用户配置窗体进行剥离出来&#xff0c;单独的放在一个Dll类库里进行操作&#xff0c;这样在其它应用程序里也能够快速的复用该类库&#xff0c;达到了快速开发软件的效果。 笔者其它模块化应用的例…

SQL面试题练习 —— 波峰波谷

来源&#xff1a;字节今日头条 目录 1 题目2 建表语句3 题解 1 题目 有如下数据&#xff0c;记录每天每只股票的收盘价格&#xff0c;请查出每只股票的波峰和波谷的日期和价格&#xff1b; 波峰定义&#xff1a;股票价格高于前一天和后一天价格时为波峰 波谷定义&#xff1a;股…

在linux下的ROS中下载超级终端Terminator ROS开发得力助手

在一般我们运行机器人包时要打开三个终端来运行&#xff0c;关闭时还要一个一个关闭&#xff08;ctrlc&#xff09;过于麻烦 现在下载用了terminator后&#xff0c;就支持一键关闭多个终端了&#xff0c;很方便&#xff0c;具体操作如下&#xff1a; sudo apt install termin…

JDBCTemplate介绍

Spring JDBC Spring框架对Spring的简单封装。提供一个JDBCTemplate对象简化JDBC开发 *步骤&#xff1a; 1、导入jar包 2、创建JDBCTemplate对象。依赖于数据源DataSource *JdbcTemplate templatenew JdbcTemplate(ds); 3、调用JdbcTemplate的方法来完成CRUD的操作 *update()&…

中国企业出海,哪些业务需要负载均衡?

国内企业出海的进程正在加速。中国的出海企业剑指跨境电商、社交、游戏、短剧等市场&#xff0c;其中尤其以跨境电商的数据最为突出。据官方数据&#xff0c;2023年我国跨境电商进出口总额达到2.38万亿元&#xff0c;比2016年增长近50倍&#xff0c;占货物贸易总规模的5.7%。 …

2024-5-9-从0到1手写配置中心Config之@ConfigurationProperties热更新

在PropertySourcesProcessor中&#xff0c;需要通过http从config-server获取配置。 使用ConfigMeta包装服务信息 在MidnightConfigService接口中添加默认实现类 继承MidnightRepositoryChangeListener接口&#xff1b;获取默认的MidnightRepository&#xff1b;创建MidnightCo…

xcode配置快速打开终端命令行工具教程

以往我们使用idea编辑器或者vscode编辑器的时候&#xff0c;我们可以快速的在编辑器下面打开终端进行相关的操作&#xff0c;但是在xcode里面却没有这么方便的功能按钮&#xff0c;真的不是很习惯&#xff0c;所以这次就来给xcode配置这么一个方便的功能。 idea的Terminal 这…