漫画:什么是优先队列

转载自  漫画:什么是优先队列

在之前的漫画中,我们介绍了二叉堆和堆排序。没看过的小伙伴可以看一看前文:

漫画:什么是二叉堆?(修正版)

漫画:什么是堆排序?

这一次,我们来讲一讲二叉堆的另外一个应用:优先队列

队列的特点是什么?

 

聪明的小伙伴们都知道,是先进先出(FIFO)

入队列:

 

出队列:

那么,优先队列又是什么样子呢?

优先队列不再遵循先入先出的原则,而是分为两种情况:

最大优先队列,无论入队顺序,当前最大的元素优先出队。

最小优先队列,无论入队顺序,当前最小的元素优先出队。

比如有一个最大优先队列,它的最大元素是8,那么虽然元素8并不是队首元素,但出队的时候仍然让元素8首先出队:

要满足以上需求,利用线性数据结构并非不能实现,但是时间复杂度较高,最坏时间复杂度O(n),并不是最理想的方式。

至于为什么最坏时间复杂度是O(n),大家可以思考下。

 

让我们回顾一下二叉堆的特性:

1.最大堆的堆顶是整个堆中的最大元素

2.最小堆的堆顶是整个堆中的最小元素

因此,我们可以用最大堆来实现最大优先队列,每一次入队操作就是堆的插入操作,每一次出队操作就是删除堆顶节点。

入队操作:

1.插入新节点5

2.新节点5上浮到合适位置。

出队操作:

1.把原堆顶节点10“出队”

2.最后一个节点1替换到堆顶位置

3.节点1下沉,节点9成为新堆顶

 

public class PriorityQueue {
private int[] array;
private int size;public PriorityQueue(){//队列初始长度32array = new int[32];
}/**
* 入队
* @param key  入队元素
*/
private void enQueue(int key) {//队列长度超出范围,扩容if(size >= array.length){resize();}array[size++] = key;upAdjust();
}/**
* 出队
*/
private int deQueue() throws Exception {if(size <= 0){throw new Exception("the queue is empty !");}//获取堆顶元素int head = array[0];//最后一个元素移动到堆顶array[0] = array[--size];downAdjust();return head;
}/**
* 上浮调整
*/
private void upAdjust() {int childIndex = size-1;int parentIndex = childIndex/2;// temp保存插入的叶子节点值,用于最后的赋值int temp = array[childIndex];while (childIndex > 0 && temp > array[parentIndex]){//无需真正交换,单向赋值即可array[childIndex] = array[parentIndex];childIndex = parentIndex;parentIndex = parentIndex / 2;}array[childIndex] = temp;
}/**
* 下沉调整
*/
private void downAdjust() {// temp保存父节点值,用于最后的赋值int parentIndex = 0;int temp = array[parentIndex];int childIndex = 1;while (childIndex < size) {// 如果有右孩子,且右孩子大于左孩子的值,则定位到右孩子if (childIndex + 1 < size && array[childIndex + 1] > array[childIndex]) {childIndex++;}// 如果父节点大于任何一个孩子的值,直接跳出if (temp >= array[childIndex])break;//无需真正交换,单向赋值即可array[parentIndex] = array[childIndex];parentIndex = childIndex;childIndex = 2 * childIndex + 1;}array[parentIndex] = temp;
}/**
* 扩容调整
*/
private void resize() {//队列容量翻倍int newSize = this.size * 2;this.array = Arrays.copyOf(this.array, newSize);
}public static void main(String[] args) throws Exception {PriorityQueue priorityQueue = new PriorityQueue();priorityQueue.enQueue(3);priorityQueue.enQueue(5);priorityQueue.enQueue(10);priorityQueue.enQueue(2);priorityQueue.enQueue(7);System.out.println("出队元素:" + priorityQueue.deQueue());System.out.println("出队元素:" + priorityQueue.deQueue());
}
}

代码中采用数组来存储二叉堆的元素,因此当元素超过数组范围的时候,需要进行resize来扩大数组长度。

 

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

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

相关文章

安全——《微服务设计》读书笔记

身份认证和授权 1.单点登录&#xff08;SSO&#xff09; 当主体试图访问一个资源&#xff0c;他会被定向到一个身份提供者那里进行身份验证&#xff0c;身份提供者验明正向后会发消息给服务提供者&#xff0c;让服务提供者来决定是否允许它访问资源。 SAML和OpenID Connect/OAu…

支付对账系统怎么设计

转载自 支付对账系统怎么设计 支付对账系统是整个支付清结算体系中具体基础性意义的一个环节&#xff0c;是确保支付平台与各类第三方支付渠道数据一致性的关键系统&#xff0c;是商户资金结算、资金划拨、资金报表等逻辑准确运行的重要前提。 支付对账涉及账单下载处理、核心…

十二个 ASP.NET Core 例子

前言 在今天的博客中&#xff0c;我将介绍十几个可以在 ASP.NET Core 应用程序中使用的简单示例。从最简单的东西开始&#xff0c;比如 Options, 中间件&#xff0c;数据库&#xff0c;甚至 Nginx 或者 Docker。 首先确定你已经执行过了 dotnet restore , 然后运行 dotnet ru…

40 道基础Dubbo 面试题及答案

转载自 40 道 Dubbo 面试题及答案 想往高处走&#xff0c;怎么能不懂 Dubbo&#xff1f; Dubbo是国内最出名的分布式服务框架&#xff0c;也是 Java 程序员必备的必会的框架之一。Dubbo 更是中高级面试过程中经常会问的技术&#xff0c;无论你是否用过&#xff0c;你都必须…

康威定律和系统设计——《微服务设计》读书笔记

康威定律 任何组织在设计一套系统时&#xff0c;所交付的设计方案在结构上都与该组织的沟通结构保持一致。 ——梅尔.康威 如何理解这句话在软件工程上的含义&#xff1f;埃里克.S.雷蒙德说&#xff1a;如果你有四个小组开发一个编译器&#xff0c;那你会得到一个四步编译器。…

Eclipse 4.9 正式发布,支持 Java 11

转载自 Eclipse 4.9 正式发布&#xff0c;支持 Java 11 来看看 Eclipse 4.9 带来了哪些新特性&#xff01; 1、外观 新增类似大纲视图的”Minimap” 间主题/暗黑主题&#xff0c;启用方法&#xff1a; Window > Show View > Other&#xff0c;然后在 Show View 对话框…

开发者需要理解的分布式原语

随着容器技术的崛起&#xff0c;开发人员的思维也从单主机扩展到了分布式。Bilgin Ibryam在Red Hat官方博客上介绍了什么是分布式原语&#xff0c;以及它与进程内原语之间的联系。本文已获得作者翻译授权&#xff0c;查看原文New Distributed Primitives for Developers。 面向…

Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码

转载自 Java 11 正式发布&#xff0c;这 8 个逆天新特性教你写出更牛逼的代码 美国时间 09 月 25 日&#xff0c;Oralce 正式发布了 Java 11&#xff0c;这是据 Java 8 以后支持的首个长期版本。 为什么说是长期版本&#xff0c;看下面的官方发布的支持路线图表。 可以看出…

JS中的命名规则

在JS中所有的可以自主命名的内容&#xff0c;都可以认为是一个标识符&#xff0c; 是标识符就应该遵守标识符的规范。 比如&#xff1a;变量名、函数名、属性名 规范&#xff1a; 1.标识符中可以含有字母、数字、_、$ 2.标识符不能以数字开头 3.标识符不能是JS中的关键字和保…

mssql on linux 安装指导

通常在本机开发环境中需要搭建所有的服务&#xff0c;还要修改本地的hosts&#xff0c;实在是不胜其烦。如今有了docker&#xff0c;完全不用污染本地环境&#xff0c;且看老司机带你搭建一个asp.net core的开发环境集群。愿你走出虚拟机&#xff0c;归来仍是干净的开发机。 教…

互联网账户系统的具体实现

转载自 互联网账户系统的具体实现 导读 在上一篇文章中我们通过场景举例的方式&#xff0c;讨论了一套相对通用的互联网业务账户系统&#xff0c;从业务模型上应该如何定义。那么除了从业务模型上进行定义外&#xff0c;在具体系统实现上又该如何设计&#xff1f;又有哪些需…

.NET 的一点历史往事:和 Java 的恩怨

在编程语言的发展历史上&#xff0c;1995年应该是个特殊的年头&#xff0c;毕竟这个年头诞生了两个后来二十多年影响深远的语言。1995年5月23日的 SunWorld 大会上面 Sun 公司高调发布了自己研发了近五年的 Java 语言和 JVM 平台。当年的十二月&#xff0c;网景公司将自己刚刚预…

这可能是史上最全 Redis 高可用解决方案总结

转载自 这可能是史上最全 Redis 高可用解决方案总结 本文主要针对 Redis 常见的几种使用方式及其优缺点展开分析。 一、常见使用方式 Redis 的几种常见使用方式包括&#xff1a; Redis 单副本&#xff1b; Redis 多副本&#xff08;主从&#xff09;&#xff1b; Redis S…

规模化微服务——《微服务设计》读书笔记

改变思维的角度&#xff1a;故障无处不在 当微服务规模化后&#xff0c;故障是无可避免的&#xff0c;以往我们总是想尽力避免故障的发生&#xff0c;而当故障实际发生时&#xff0c;我们往往束手无策。我们花了很多时间在流程设计和应用设计的层面上来阻止故障的发生&#xff…

JS中的基本和引用类型传递的比较

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><script type"text/javascript">/** 基本数据类型* String Number Boolean Null Undefined* * 引用数据类型* Object* * JS中的变量都是保…

如何在 ASP.NET Core 中发送邮件

前言 我们知道目前 .NET Core 还不支持 SMTP 协议&#xff0c;当我么在使用到发送邮件功能的时候&#xff0c;需要借助于一些第三方组件来达到目的&#xff0c;今天给大家介绍两款开源的邮件发送组件&#xff0c;它们分别是 MailKit 和 FluentEmail &#xff0c; 下面我对它们…

一文搞懂 Java 线程中断

转载自 一文搞懂 Java 线程中断 在之前的一文《如何"优雅"地终止一个线程》中详细说明了 stop 终止线程的坏处及如何优雅地终止线程&#xff0c;那么还有别的可以终止线程的方法吗&#xff1f;答案是肯定的&#xff0c;它就是我们今天要分享的——线程中断。 下面…