【算法基础实验】排序-最小优先队列MinPQ

优先队列

理论知识

MinPQ(最小优先队列)是一种常见的数据结构,用于有效管理一组元素,其中最小元素可以快速被检索和删除。这种数据结构广泛应用于各种算法中,包括图算法(如 Dijkstra 的最短路径算法和 Prim 的最小生成树算法)、事件驱动的模拟、调度任务等。

MinPQ 的核心操作

MinPQ 主要支持以下几种操作:

  1. 插入(Insert) - 将一个新元素添加到优先队列中。
  2. 查找最小(Find Minimum) - 获取优先队列中的最小元素,但不从队列中删除它。
  3. 删除最小(Delete Minimum) - 移除并返回优先队列中的最小元素。
  4. 判断是否为空(IsEmpty) - 检查优先队列是否为空。
  5. 大小(Size) - 返回优先队列中的元素数量。

MinPQ 的实现方式

MinPQ 可以用多种方式实现,其中最常见的是使用二叉堆(Binary Heap)结构,特别是最小堆。最小堆是一个完全二叉树,可以用数组来有效表示,具有以下性质:

  • 每个节点的值都小于或等于其子节点的值。
  • 树是完全填满的,除了最底层,最底层从左向右填充,直到填满。

使用最小堆的优势

使用最小堆实现 MinPQ 的优势在于其操作的高效性:

  • 插入操作删除最小操作的时间复杂度为 O(log n),其中 n 是队列中的元素数量。
  • 查找最小操作的时间复杂度为 O(1),因为最小元素总是位于堆的根部。

应用示例

在许多实时系统和性能要求高的环境中,MinPQ 用来保证重要任务优先处理,或确保数据的最小值可以迅速访问。例如,在网络路由算法中,需要快速找到最短的未处理路径;在模拟环境中,优先处理最早发生的事件。

总的来说,MinPQ 是一种非常实用的数据结构,通过最小堆实现可以提供高效的性能,适用于需要快速访问和删除最小元素的各种应用场景。

在这里插入图片描述

实验数据

tinyPQ.txt测试数据内容

P Q E - X A M - P L E -

算法流程

在这里插入图片描述

代码实现

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;public class myMinPQ<Key extends Comparable<Key>> {private Key[] pq;private int n = 0;public myMinPQ(int initN){pq = (Key[]) new Comparable[initN+1];}public myMinPQ(){this(1);}public myMinPQ(Key[] keys){n = keys.length;pq = (Key[]) new Comparable[n+1];}private void resize(int capacity) {Key[] temp = (Key[]) new Comparable[capacity];for (int i = 1; i <= n; i++) {temp[i] = pq[i];}pq = temp;}public boolean isEmpty(){return n == 0;}public int size(){return n;}public void insert(Key v){pq[++n] = v;if (n == pq.length - 1) resize(2 * pq.length);swim(n);}public Key delMin(){Key min = pq[1];exch(1,n--);pq[n+1] = null;sink(1);if ((n > 0) && (n == (pq.length - 1) / 4)) resize(pq.length / 2);return min;}private boolean greater(int i, int j){return pq[i].compareTo(pq[j]) > 0;}private void exch(int i, int j){Key t = pq[i]; pq[i]=pq[j]; pq[j]=t;}private void swim(int k){while(k>1 && greater(k/2, k)) {exch(k/2,k);k=k/2;}}private void sink(int k){while(2*k <= n){int j = 2*k;if(j < n && greater(j, j+1)) j++;if(!greater(k,j)) break;exch(k,j);k = j;}}public static void main(String[] args) {myMinPQ<String> pq = new myMinPQ<String>();while (!StdIn.isEmpty()) {String item = StdIn.readString();if (!item.equals("-")) pq.insert(item);else if (!pq.isEmpty()) StdOut.print(pq.delMin() + " ");}StdOut.println("(" + pq.size() + " left on pq)");}
}

代码讲解

这段 Java 代码定义了一个名为 myMinPQ 的类,实现了一个最小优先队列(Min Priority Queue)。这个优先队列使用最小堆来维护元素的顺序,以确保能够快速地插入新元素并删除最小元素。下面是对这段代码各部分的详细解释:

类定义和泛型

  • myMinPQ<Key extends Comparable<Key>>: 类定义使用泛型 Key,这意味着队列中的元素必须实现 Comparable 接口,使得元素之间可以比较大小。

字段

  • private Key[] pq;: 存储堆元素的数组。数组从索引1开始使用,以简化父节点和子节点的索引计算。
  • private int n = 0;: 表示堆中元素的数量。

构造函数

  • myMinPQ(int initN): 接受一个初始容量 initN 并创建一个容量为 initN + 1 的数组。
  • myMinPQ(): 无参构造函数,默认初始化容量为1。
  • myMinPQ(Key[] keys): 接受一个数组 keys 并用其初始化优先队列。

方法

  • resize(int capacity): 当数组容量不足以存储更多元素时,调用此方法以调整数组大小。
  • isEmpty(): 检查优先队列是否为空。
  • size(): 返回队列中的元素数量。
  • insert(Key v): 向优先队列中插入一个新元素。使用 swim 方法确保最小堆的属性。
  • delMin(): 从队列中删除并返回最小元素。使用 sink 方法调整堆以维持最小堆的属性。
  • greater(int i, int j): 比较堆中索引 ij 的元素大小。
  • exch(int i, int j): 交换堆中索引 ij 的元素。
  • swim(int k): 上浮操作,调整元素位置以维持堆的顺序。
  • sink(int k): 下沉操作,调整元素位置以维持堆的顺序。

主函数

  • main(String[] args): 主函数从标准输入读取字符串,插入到优先队列中。如果读取到的字符串是 "-" 并且队列不为空,则删除并打印最小元素。最终打印队列中剩余元素的数量。

这个类的实现利用了二叉堆的特性,确保每次插入和删除操作的时间复杂度为 O(log n),从而使得操作效率较高。通过调整数组大小的方式,该实现还可以动态地调整内存使用,以适应不同的使用场景。

实验

代码编译

$ javac myMinPQ.java

代码运行

$ java myMinPQ < data\tinyPQ.txt
E A E (6 left on pq)

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

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

相关文章

python中的矩阵操作

1 矩阵的每行加上同一行 print(np.array([[0,0,1],[1,1,1],[2,2,1]])[1,1,1])2 两个矩阵AB(相同列数不同行)拼接&#xff0c;B按行拼接在A后面 np.row_stack((A,B)))3 一个矩阵的每个元素都加上同一个常数 print(np.array([[0,0,1],[1,1,1],[2,2,1]])1)矩阵中每个数都会加1 …

高斯数据库创建存储过程

CREATE PROCEDURE 语法格式 CREATE [ OR REPLACE ] PROCEDURE procedure_name [ ( {[ argmode ] [ argname ] argtype [ { DEFAULT | : | } expression ]}[,…]) ] [ { IMMUTABLE | STABLE | VOLATILE } | { SHIPPABLE | NOT SHIPPABLE } | {PACKAGE} | [ NOT ] LEAKPROOF | {…

mysql的JDBC

MYSQL的JDBC 流程&#xff1a; 注册和加载驱动(可以省略)&#xff08;导入mysql的jdbc的驱动库&#xff09;&#xff08;Class.forName(“com.mysql.jdbc.Driver”);&#xff09; 获取连接 Connection 获取 Statement 对象 使用 Statement 对象执行 SQL 语句 返回结果集 …

GPT-4o 免费开放!体验 AI 对话的无限可能!手把手教你普通用户如何切换到4o版本使用!

大家好&#xff0c;我是影子。今天一觉醒来&#xff0c;发现朋友圈传开了GPT-4o可以免费使用了。 相信大家都使用过GPT-3.5的版本&#xff0c;但是无论是智能程度还是联网查询等一些需求都无法给我们实现&#xff0c;这不&#xff0c;4o的出现直接解决了这些问题。 下面影子将…

ROS2 - 创建项目 (Ubuntu22.04)

本文简述&#xff1a;在 Ubuntu22.04 系统中使用 VS CODE 来搭建一个ROS2开发项目。 1. 创建工作空间 本文使用 Ubuntu 22.04&#xff0c; 已安装配置完成 VS Code&#xff0c;C 环境&#xff08;g/gdb&#xff09; 1.1 创建目录 选择文件夹作为工作空间&#xff0c;并在这…

空号检测接口如何对接?

手机运营商空号检测接口又叫空号过滤查询接口、手机号状态检测查询接口&#xff0c;指的是输入手机号&#xff0c;查询其在网活跃度&#xff0c;返回包括空号、实号、停机、库无、沉默号、风险号等状态。那么运营商空号检测接口如何对接呢&#xff1f; 首先我们找到一家有手机…

vb6 ado连接数据库 oledb Microsoft OLE DB Provider for SQL Server 连接字符串

SQL Server 2000 标准安全 Providersqloledb;Data SourcemyServerAddress;Initial CatalogmyDataBase;User IdmyUsername;PasswordmyPassword; SQL Server 2000SQL服务器7.0 可信连接 Providersqloledb;Data SourcemyServerAddress;Initial CatalogmyDataBase;Integrated Secur…

排序-冒泡排序(bubble sort)

冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它重复地遍历待排序的数列&#xff0c;一次比较两个元素&#xff0c;如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复地进行直到没有再需要交换&#xff0c;也就是说该数列已经排序完成…

Weblogic 任意文件上传漏洞(CVE-2018-2894)

1 漏洞描述 CVE-2018-2894漏洞存在于Oracle WebLogic Server的Web服务测试页面&#xff08;Web Service Test Page&#xff09;中。这个页面允许用户测试Web服务的功能&#xff0c;但在某些版本中&#xff0c;它包含了一个未经授权的文件上传功能。攻击者可以利用这个漏洞&…

数据特征降维 | 主成分分析(PCA)附Python代码

主成分分析(Principal Component Analysis,PCA)是一种常用的数据降维技术和探索性数据分析方法,用于从高维数据中提取出最重要的特征并进行可视化。 PCA的基本思想是通过线性变换将原始数据投影到新的坐标系上,使得投影后的数据具有最大的方差。这些新的坐标轴称为主成分…

苹果cms:搜索功能的开关与设置

今天有个小伙伴问了个关于苹果cms搜索的问题&#xff1a;直接搜演员搜索不到影片信息&#xff08;如下图&#xff09; 1、我们拿演员王宝强为例&#xff1a;搜索王宝强后结果显示无相关视频 2、但是我们搜索王宝强主演的“大闹天竺”后却能得到关于王宝强的影片信息。这是为什…

springboot以tomcat方式启动后报错

使用idea启动tomcat时&#xff0c;报错。将程序打包到linux后&#xff0c;仍报相同错误。 错误如下&#xff1a; 一个或多个筛选器启动失败。完整的详细信息将在相应的容器日志文件中找到 严重[localhost] org.apache.catalina.core.StandardContext.startInternal 由于之前的…

代理模式的理解

文章目录 前言一、代理模式的定义和优、缺点定义优点缺点 二、代码演示案例1.静态代理2.JDK动态代理3.CGLIB动态代理 总结 前言 代理模式常见的使用场景包括&#xff1a; 需要对对象的访问进行控制或限制的情况。 需要在访问对象时执行额外的操作&#xff0c;例如记录日志、收…

内啡肽的产生

内啡肽的产生 短视频、直播和游戏等娱乐活动可以刺激多巴胺分泌&#xff0c;让人感到兴奋和愉悦。这些短暂的快乐却会让我们逐渐上瘾&#xff0c;难以自拔。不知不觉中&#xff0c;我们忽略了时间的流逝&#xff0c;满足于现状&#xff0c;失去了追求更高目标的动力。 越是富…

跨ROS系统通信:使用TCP实现节点间的直连

当涉及到在机器人操作系统&#xff08;ROS&#xff09;环境中的通信时&#xff0c;标准做法通常是在同一个ROS网络内通过话题和服务进行。但在某些特定情况下&#xff0c;比如当你有两个分布在不同网络中的ROS系统时&#xff0c;标准的通信方法可能不太适用。此时&#xff0c;一…

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第21课-购买烟花插件

【WEB前端2024】开源智体世界&#xff1a;乔布斯3D纪念馆-第21课-购买烟花插件 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎…

OpenAI 5月13日推出的ChatGPT4o模型带来了什么新东西及我们需要注意什么

前言 OpenAI再次发布了新一代模型&#xff0c;可惜不是GPT5&#xff0c;发布会很长&#xff0c;所以我尝试看了一些自媒体对发布会做的总结视频&#xff0c;但是我发现这些自媒体制作的视频普遍很“营销号”味且总结的不全面&#xff0c;所以我看了发布会并尝试做了总结。 正…

OmniDrive:具有 3D 感知推理和规划功能的自动驾驶整体 LLM-智体框架

24年5月北理工、Nvidia和华中科大的论文“OmniDrive&#xff1a;A Holistic LLM-Agent Framework for Autonomous Driving with 3D Perception Reasoning and Planning”。 多模态大语言模型&#xff08;MLLMs&#xff09;的进展导致了对基于LLM的自动驾驶的兴趣不断增长&…

软件各阶段资料(需求设计,系统架构,开发文档,测试文档,运维阶段的部署维护文档,概要设计,详细设计)

一、 引言 &#xff08;一&#xff09; 编写目的 &#xff08;二&#xff09; 范围 &#xff08;三&#xff09; 文档约定 &#xff08;四&#xff09; 术语 二、 项目概要 &#xff08;一&#xff09; 建设背景 &#xff08;二&#xff09; 建设目标 &#xff08;三&#xff0…

解决Jmeter报错 :Error generating the report: java.lang.NullPointerException

当我们在使用命令行的方式来执行jmeter 脚本的时候&#xff0c;例如 ./jmeter -n -t /opt/jmeter/script/test.jmx -Juser50 -Jtime100 -l /opt/jmeter/script/restult2.jtl 上面脚本的含义解释如下&#xff1a; -n -t 通过命令行的方式执行脚本test.jmx -Juser50 并发用户…