优先级队列(堆)的实现

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,一经查实,立即删除!

相关文章

框架vnode,工厂模式实现的例子

工厂模式&#xff0c; vue3 <div><span>静态文字</span><span :id"hello" class"bar">{{ msg }}</span> </div> import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, open…

堆的实现

前言&#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…

Python面试宝典:虚拟环境概念以及虚拟环境管理面试题(1000加python面试题助你轻松捕获大厂Offer)

Python面试宝典:1000加python面试题助你轻松捕获大厂Offer【第一部分:Python基础:第九章:Python虚拟环境:第一节:虚拟环境概念以及虚拟环境管理】 第九章:Python虚拟环境第一节:虚拟环境概念以及虚拟环境管理1.1、为什么需要虚拟环境?1.2、虚拟环境管理工具1.1.1. ven…

02_前端三大件HTML

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

浅谈JMeter工具学习基础要求和性能测试价值

浅谈JMeter工具学习基础要求和性能测试价值 JMeter工具学习基础要求 JMeter工具学习基础要求&#xff1a;   在深入学习JMeter之前&#xff0c;需要具备一定的计算机网络基础知识、编程基础&#xff0c;理解HTTP协议、TCP/IP协议栈等底层通信原理&#xff0c;这样才能更好地…

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…

CentOS防火墙管理及配置

CentOS防火墙管理及配置 防火墙配置介绍防火墙服务管理防火墙配置重载防火墙端口查看 防火墙配置介绍 firewalld为防火墙服务名称&#xff0c;centos7以前是使用iptables firewall-cmd&#xff1a;防火墙配置命令行工具 /etc/firewalld/&#xff1a;防火墙相关配置文件目录 防火…

分析工具:Accessibility Insights、spy、Inspect

1、Accessibility Insights 官网&#xff1a;https://accessibilityinsights.io/ 文档&#xff1a;https://accessibilityinsights.io/docs/web/overview/ Github&#xff1a;https://github.com/microsoft/accessibility-insights-windows Windows 官方推荐的辅助工具。用来查…

弹性盒子布局,flex布局

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

算法随想录第十三天打卡|239. 滑动窗口最大值,347.前 K 个高频元素

239. 滑动窗口最大值 &#xff08;一刷至少需要理解思路&#xff09; 之前讲的都是栈的应用&#xff0c;这次该是队列的应用了。 本题算比较有难度的&#xff0c;需要自己去构造单调队列&#xff0c;建议先看视频来理解。 题目链接/文章讲解/视频讲解&#xff1a;代码随想录 c…

使用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…