【数据结构与算法】队列

文章目录

  • 一:队列
    • 1.1 队列的概念
    • 1.2 队列的介绍
    • 1.3 队列示意图
  • 二:数组模拟队列
    • 2.1 介绍
    • 2.2 思路
    • 2.3 代码实现
      • 2.3.1 定义队列基本信息
      • 2.3.2 初始化队列
      • 2.3.3 判断队列是否满,是否为空
      • 2.3.4 添加数据到队列
      • 2.3.5 获取队列数据,出队列
      • 2.3.6 显示队列所有数据
      • 2.3.7 显示队列头数据
      • 2.3.8 源码奉上
    • 2.4 测试ArrayQueue
    • 2.5 问题分析并优化
  • 三:数组模拟环形队列
    • 3.1 分析
    • 3.2 思路
    • 3.3 代码实现

一:队列

1.1 队列的概念

  • 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特点。
  • 入队列:进行插入操作的一端称为队尾 。
  • 出队列:进行删除操作的一端称为队头。

例如:比如生活中排队买东西,先排队的先购买

1.2 队列的介绍

  1. 队列是一个有序列表,可以用数组或是链表来实现。
  2. 遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出

1.3 队列示意图

在这里插入图片描述

二:数组模拟队列

2.1 介绍

  • 队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队列的最大容量。

  • 因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变,如图所示:

  • 在这里插入图片描述

2.2 思路

当我们将数据存入队列时称为”addQueue”,addQueue 的处理需要有两个步骤:思路分析

  1. 将尾指针往后移:rear+1 , 当front == rear 【空】
  2. 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear所指的数组元素中,否则无法存入数据。 rear == maxSize - 1[队列满]

注:
rear 是队列最后[含]
front 是队列最前元素[不含]

2.3 代码实现

2.3.1 定义队列基本信息

 /*** 最大容量*/private int maxSize;/*** 队列头*/private int front;/*** 队列尾*/private int rear;/*** 该数组用于存放数据*/private int[] arr;

2.3.2 初始化队列

/*** 初始化队列构造器** @param arrMaxSize*/public ArrayQueue(int arrMaxSize) {maxSize = arrMaxSize;arr = new int[arrMaxSize];//指向队列头部的前一个位置,不包含头部front = -1;//指向队列尾部具体数据rear = -1;}

2.3.3 判断队列是否满,是否为空

/*** 判断队列是否满** @return*/public boolean isFull() {return rear == maxSize - 1;}/*** 判断队列是否为空** @return*/public boolean isEmpty() {return front == rear;}

2.3.4 添加数据到队列

public void addQueue(int n) {//判断队列是否满,满了就无法添加数据if (isFull()) {System.out.println("队列满了,无法添加数据");return;}//添加数据让rear后移rear++;arr[rear] = n;}

2.3.5 获取队列数据,出队列

  /*** 获取队列数据,出队列** @return*/public int getQueue() {//判断队列是否为空if (isEmpty()) {throw new RuntimeException("队列为空,无法取出数据");}front++;return arr[front];}

2.3.6 显示队列所有数据

   /*** 显示队列所有数据*/public void showQueue() {//判断队列是否为空if (isEmpty()) {System.out.println("队列为空,没有数据");}for (int i = 0; i < arr.length; i++) {System.out.printf("arr[%d]=%d\n", i, arr[i]);}}

2.3.7 显示队列头数据

 /*** 显示队列头数据** @return*/public int headQueue() {//判断队列是否为空if (isEmpty()) {throw new RuntimeException("队列为空,没有数据");}return arr[front + 1];}

2.3.8 源码奉上


/*** 队列头部输出数据,尾部输入数据*/
class ArrayQueue {/*** 最大容量*/private int maxSize;/*** 队列头*/private int front;/*** 队列尾*/private int rear;/*** 该数组用于存放数据*/private int[] arr;/*** 初始化队列构造器** @param arrMaxSize*/public ArrayQueue(int arrMaxSize) {maxSize = arrMaxSize;arr = new int[arrMaxSize];//指向队列头部的前一个位置,不包含头部front = -1;//指向队列尾部具体数据rear = -1;}/*** 判断队列是否满** @return*/public boolean isFull() {return rear == maxSize - 1;}/*** 判断队列是否为空** @return*/public boolean isEmpty() {return front == rear;}/*** 添加数据到队列*/public void addQueue(int n) {//判断队列是否满,满了就无法添加数据if (isFull()) {System.out.println("队列满了,无法添加数据");return;}//添加数据让rear后移rear++;arr[rear] = n;}/*** 获取队列数据,出队列** @return*/public int getQueue() {//判断队列是否为空if (isEmpty()) {throw new RuntimeException("队列为空,无法取出数据");}front++;return arr[front];}/*** 显示队列所有数据*/public void showQueue() {//判断队列是否为空if (isEmpty()) {System.out.println("队列为空,没有数据");}for (int i = 0; i < arr.length; i++) {System.out.printf("arr[%d]=%d\n", i, arr[i]);}}/*** 显示队列头数据** @return*/public int headQueue() {//判断队列是否为空if (isEmpty()) {throw new RuntimeException("队列为空,没有数据");}return arr[front + 1];}}

2.4 测试ArrayQueue

public class ArrayQueueDemo {public static void main(String[] args) {ArrayQueue queue = new ArrayQueue(3);//接收用户输入char key = ' ';Scanner scanner = new Scanner(System.in);boolean loop = true;while (loop) {System.out.println("s(show):显示队列");System.out.println("e(exit):退出程序");System.out.println("a(add):添加数据队列");System.out.println("g(get):取出数据队列");System.out.println("h(head):查看头队列数据");key = scanner.next().charAt(0);switch (key) {case 's':queue.showQueue();break;case 'a':System.out.println("输入一个数字");int value = scanner.nextInt();queue.addQueue(value);break;case 'g':try {int res = queue.getQueue();System.out.printf("取出的数据为%d\n",res);} catch (Exception e) {System.out.println(e.getMessage());}break;case 'h':try {int res = queue.headQueue();System.out.printf("队列头数据为%d\n",res);} catch (Exception e) {System.out.println(e.getMessage());}case 'e':scanner.close();loop = false;default:break;}}System.out.println("程序退出");}}

2.5 问题分析并优化

问题:目前数组使用一次就无法使用,没有达到复用的效果
优化:将数组改成环形队列,进行取模

三:数组模拟环形队列

3.1 分析

对前面的数组模拟队列的优化,充分利用数组。因此将数组看做是一个环形的。(通过取模的方式来实现即可)

3.2 思路

  1. front的含义做出如下调整:front就指向队列的第一个元素,即arr[front]就是队列的第一个元素。
  2. rear的含义做出如下调整:rear指向队列最后一个元素的后一个位置。空出一个空间做约定。
  3. 队列满的条件:(rear+1)%maxSize = front;
  4. 队列空的条件:rear == front;
  5. front和rear的初始值都为0;
  6. 队列中有效数据个数:(rear + maxSize - front)% maxSize;

3.3 代码实现

package com.sysg.dataStructuresAndAlgorithms.queue;import java.util.Scanner;public class CircleArrayQueueDemo {public static void main(String[] args) {//长度为4,有效长度为3,有一个预留的空间CircleArrayQueue queue = new CircleArrayQueue(4);//接收用户输入char key = ' ';Scanner scanner = new Scanner(System.in);boolean loop = true;while (loop) {System.out.println("s(show):显示队列");System.out.println("e(exit):退出程序");System.out.println("a(add):添加数据队列");System.out.println("g(get):取出数据队列");System.out.println("h(head):查看头队列数据");key = scanner.next().charAt(0);switch (key) {case 's':queue.showQueue();break;case 'a':System.out.println("输入一个数字");int value = scanner.nextInt();queue.addQueue(value);break;case 'g':try {int res = queue.getQueue();System.out.printf("取出的数据为%d\n",res);} catch (Exception e) {System.out.println(e.getMessage());}break;case 'h':try {int res = queue.headQueue();System.out.printf("队列头数据为%d\n",res);} catch (Exception e) {System.out.println(e.getMessage());}case 'e':scanner.close();loop = false;default:break;}}System.out.println("程序退出");}
}class CircleArrayQueue {/*** 最大容量*/private int maxSize;/*** 队列头* 1. front的含义做出如下调整:front就指向队列的第一个元素,即arr[front]就是队列的第一个元素。*/private int front;/*** 队列尾* 2. rear的含义做出如下调整:rear指向队列最后一个元素的后一个位置。空出一个空间做约定。*/private int rear;/*** 该数组用于存放数据*/private int[] arr;/*** 初始化队列构造器** @param arrMaxSize*/public CircleArrayQueue(int arrMaxSize) {maxSize = arrMaxSize;arr = new int[arrMaxSize];front = 0;rear = 0;}/*** 判断队列是否满** @return*/public boolean isFull() {//例:front = 1,rear = 5,maxSize = 5,此时队列就满了return (rear + 1) % maxSize == front;}/*** 判断队列是否为空** @return*/public boolean isEmpty() {return front == rear;}/*** 添加数据到队列*/public void addQueue(int n) {//判断队列是否满,满了就无法添加数据if (isFull()) {System.out.println("队列满了,无法添加数据");return;}//直接将数据加入arr[rear] = n;//将rear后移,这里必须考虑取模rear = (rear + 1) % maxSize;}/*** 获取队列数据,出队列** @return*/public int getQueue() {//判断队列是否为空if (isEmpty()) {throw new RuntimeException("队列为空,无法取出数据");}//这里需要分析出front是指向队列的第一个元素//1.先把front的值保存到一个临时的变量//2.将front后移,考虑取模//3.将临时变量保存int value = arr[front];front = (front + 1) % maxSize;return value;}/*** 显示队列所有数据*/public void showQueue() {//判断队列是否为空if (isEmpty()) {System.out.println("队列为空,没有数据");}//从front开始遍历,遍历多少个元素for (int i = front; i < front + getSize(); i++) {System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);}}/*** 获取有效数据大小* @return*/public int getSize() {return (rear + maxSize - front) % maxSize;}/*** 显示队列头数据** @return*/public int headQueue() {//判断队列是否为空if (isEmpty()) {throw new RuntimeException("队列为空,没有数据");}return arr[front];}}

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

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

相关文章

Shell学习笔记之基础部分

Shell基础&#xff1a; 查看操作系统支持的shell&#xff1a; [rootrhel9 ansible]# cat /etc/shells /bin/sh /bin/bash /usr/bin/sh /usr/bin/bashShell的基本元素&#xff1a; 声明&#xff1a;声明用哪个命令解释器来解释并执行当前脚本文件中的语句&#xff0c;一般写的…

浅谈5G技术会给视频监控行业带来的一些变革情况

5G是第五代移动通信技术&#xff0c;能够提供更高的带宽和更快的传输速度&#xff0c;这将为视频技术的发展带来大量机会。随着5G技术的逐步普及与商用&#xff0c;人们将能够享受到更加流畅的高清视频体验&#xff0c;并且5G技术还拥有更低的延迟和更高的网络容量。这些优势不…

Vue中实现自动匹配搜索框内容 关键字高亮文字显示

实现效果如下: 1.首先需要给输入框进行双向绑定 2.拿到搜索的结果去渲染页面 将返回的结果和搜索的关键字进行比对 如果相同的 就变红 上代码 html部分 //输入框<div class"search"><div class"shuru"><input type"请输入要查询的…

论文阅读——Imperceptible Adversarial Attack via Invertible Neural Networks

Imperceptible Adversarial Attack via Invertible Neural Networks 作者&#xff1a;Zihan Chen, Ziyue Wang, Junjie Huang*, Wentao Zhao, Xiao Liu, Dejian Guan 解决的问题&#xff1a;虽然视觉不可感知性是对抗性示例的理想特性&#xff0c;但传统的对抗性攻击仍然会产…

机器学习:基本介绍

机器学习介绍 Hnad-crafted rules Hand-crafted rules&#xff0c;叫做人设定的规则。那假设今天要设计一个机器人&#xff0c;可以帮忙打开或关掉音乐&#xff0c;那做法可能是这样&#xff1a; 设立一条规则&#xff0c;就是写一段程序。如果输入的句子里面看到**“turn of…

Android开发之性能优化:过渡绘制解决方案

1. 过渡绘制 屏幕上某一像素点在一帧中被重复绘制多次&#xff0c;就是过渡绘制。 下图中多个卡片跌在一起&#xff0c;但是只有第一个卡片是完全可见的。背后的卡片只有部分可见。但是Android系统在绘制时会将下层的卡片进行绘制&#xff0c;接着再将上层的卡片进行绘制。但其…

Vue2-配置脚手架、分析脚手架、render函数、ref属性、props配置项、mixin配置项、scoped样式、插件

&#x1f954;:总有一段付出了没有回报的日子 是在扎根 更多Vue知识请点击——Vue.js VUE2-Day6 配置脚手架脚手架结构render函数vue.js与vue.runtime.xxx.js的区别引入render函数为什么要引入残缺的vue呢&#xff1f; 脚手架默认配置ref属性props配置项传递数据接收数据注意点…

如何利用 EMC 模型解决能源服务提供商的瓶颈

01. 什么是合同能源管理&#xff1f; 合同能源管理(EMC-Energy Management Contract) 是一种新型的市场化节能机制,其实质就是以减少的能源费用来支付节能项目全部成本的节能投资方式。&#xff1a;节能服务公司与用能单位以契约形式约定节能项目的节能目标&#xff0c;节能服…

环境与能源创新专题:地级市绿色创新、碳排放与环境规制数据

数据简介&#xff1a;推动绿色发展&#xff0c;促进人与自然和谐共生是重大战略举措。绿色发展强调“绿水青山就是金山银山”&#xff0c;人与自然和谐共生重在正确处理生态环境保护与经济发展的关系。在着力于实现绿色发展的过程中&#xff0c;绿色创新是绿色发展的重要驱动因…

ComponentOne Studio ASP.NET MVC Crack

ComponentOne Studio ASP.NET MVC Crack FlexReport增强功能 添加了对在Microsoft Windows上部署Microsoft Azure的支持。 添加了对显示嵌入字体的支持。 .NET标准版的经典C1PDF(Beta版) GrapeCity的经典C1Pdf库现在提供了基于Microsoft.NET标准的版本。在任何.NET应用程序(包括…

如何让你的图片服务也有类似OSS的图片处理功能

原文链接 前言 有自己机房的公司一般都有一套存储系统用于存储公司的图片、视频、音频、文件等数据&#xff0c;常见的存储系统有以NAS、FASTDFS为代表的传统文件存储&#xff0c;和以Minio为代表的对象存储系统&#xff0c;随着云服务的兴起很多公司逐渐将数据迁移到以阿里云…

【C语言】深度剖析数据在内存中的存储

一、数据类型详细介绍 1、数据类型介绍 &#xff08;1&#xff09;基本的内置类型 //内置类型就是C语言自带的类型char //字符数据类型 short //短整型 int //整形 long //长整型 long long //更长的整形 float //单精度浮点数 double …

米尔瑞萨RZ/G2L开发板-02 ffmpeg的使用和RTMP直播

最近不知道是不是熬夜太多&#xff0c;然后记忆力减退了&#xff1f; 因为板子回来以后我就迫不及待的试了一下板子&#xff0c;然后发现板子有SSH&#xff0c;但是并没有ffmpeg&#xff0c;最近总是在玩&#xff0c;然后今天说是把板子还原一下哇&#xff0c;然后把官方的固件…

【Linux操作系统】深入探索Linux进程:创建、共享与管理

进程的创建是Linux系统编程中的重要概念之一。在本节中&#xff0c;我们将介绍进程的创建、获取进程ID和父进程ID、进程共享、exec函数族、wait和waitpid等相关内容。 文章目录 1. 进程的创建1.1 函数原型和返回值1.2 函数示例 2. 获取进程ID和父进程ID2.1 函数原型和返回值2.…

java练习4.快速查找

题目: 数组 arr[6,1,3,7,9,8,5,4,2],用快速排序进行升序排序. import java.util.Random;public class recursionDemo {public static void main(String[] args) {/*快速排序:* 第一轮:以0索引为基准数,确定基准数在数组正确的位置,* 比基准数小的放到左边,比基准数大的放在右边…

Markdown 入门基础

文章目录 Markdown 是什么&#xff1f;为什么要使用 Markdown?工欲善其事&#xff0c;必先利其器Markdown 的工作原理Markdown 有什么用&#xff1f;网站文件资料笔记书籍演示文稿邮件文档 Markdown 方言其它资源 Markdown 是什么&#xff1f; Markdown 是一种轻量级的标记语…

【c语言】通讯录(动态版+文件+背景音乐)含源码

开饭了&#xff0c;之前写的通讯录&#xff0c;是否会有人觉得申请1000人的空间是不是有点用不上呀&#xff0c;怎么才能做到要多少申请多少个呢&#xff1f;&#xff1f;我们学完动态内存管理&#xff0c;和文件的相关操作&#xff0c;终于可以继续完善我们的通讯录了 船新版本…

(搜索) 剑指 Offer 12. 矩阵中的路径 ——【Leetcode每日一题】

❓剑指 Offer 12. 矩阵中的路径 难度&#xff1a;中等 给定一个 m * n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构…

UE4/5数字人MetaHuman的控制绑定资产使用

开始操作 首先我们创建一个关卡序列&#xff1a; 打开后将我们的数字人放进去【右键&#xff0c;第一个添加进去】&#xff1a; 我们会自动进入动画模式&#xff0c;没有的话&#xff0c;就自己进入一下&#xff0c; 然后我们去寻找我们的控制绑定资产。 找到控制绑定资产 …

牛客网华为OD前端岗位,面试题库练习记录01

题目一 质数因子 功能:输入一个正整数&#xff0c;按照从小到大的顺序输出它的所有质因子&#xff08;重复的也要列举&#xff09;&#xff08;如180的质因子为2 2 3 3 5 &#xff09; JavaScript Node ACM模式 const rl require("readline").createInterface({ i…