漫画:什么是优先队列

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

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

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

漫画:什么是堆排序?

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

队列的特点是什么?

 

聪明的小伙伴们都知道,是先进先出(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…

抽象和封装

一、软件出现的目的是为了&#xff1a; 1.用计算机语言描述现实世界。 2.用计算机解决现实世界中的问题。 二、面向对象&#xff1a; 1.与人类的思维习惯一致 2.代码可重用性高&#xff0c;可靠性高。 三、从现实世界中抽象出类&#xff1a; 1.发现类 2.发现类的属性 3.发现类的…

支付对账系统怎么设计

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

十二个 ASP.NET Core 例子

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

Opencv FFmpeg Ubuntu下编译问题

FFmpeg转码错误Cannot load libcuda.so.1 https://blog.csdn.net/yzhang6_10/article/details/81349532 srs2.0 安装启动 https://my.oschina.net/fengjihu/blog/413710 SRS-HLS服务的部署 https://blog.csdn.net/dengjoe/article/details/52698423 ubuntu编译ffmpeg并且demo测…

40 道基础Dubbo 面试题及答案

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

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

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

Ubuntu下C++代码调用可执行文件。

例如&#xff1a;已经存在一个编译好的c可执行文件&#xff1a; 简单代码&#xff08;第一个可执行文件&#xff09; vim hello.cpp #include <iostream> using namespace std; int main(){cout<<"Ubuntu调用C可执行文件成功"<<endl;return 0; }编…

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 对话框…

Ubuntu C++ Thread Sleep

#include #include <unistd.h> using namespace std; int main() { cout << “nitrate”; cout << flush; usleep(1000000); cout << “firtilizers”; return 0; } usleep函数能把线程挂起一段时间&#xff0c; 单位是微秒&#xff08;千分之一毫秒…

JS书写规则

1.JS严格区分大小写 2.JS中每条语句以分号(;)结尾如果不写分号&#xff0c;浏览器会自动添加&#xff0c;但是会消耗一些系统资源&#xff0c; 而且有些时候&#xff0c;浏览器会加错分号&#xff0c;所以在开发中分号必须写 3.JS中会自动忽略多个空格和换行&#xff0c;所以…

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

随着容器技术的崛起&#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;看下面的官方发布的支持路线图表。 可以看出…

c/c++ 字符串分割

c/c 字符串分割 vector<string> split_string(const char *str, const char *pattern) {char * strc (char*)str;vector<string> res;char* temp strtok(strc, pattern);while(temp ! NULL){res.push_back(string(temp));temp strtok(NULL, pattern);}return re…

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;又有哪些需…