02队列及代码实现

news2024/11/25 6:59:23

队列介绍

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

在这里插入图片描述

数组模拟队列

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

  2. 因为队列的输入、输出分别是前后端来处理,因此需要两个变量front及rear分别记录队列前后端的下标,front会随着数据输出而改变,而rear则是随着数据输入而改变,具体如图。
    在这里插入图片描述

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

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

第一版代码:

package com.queue;

import java.util.Scanner;

public class ArrayQueueDemo {
    public static void main(String[] args) {
        //创建一个队列
        ArrayQueue arrayQueue = new ArrayQueue(3);
        // 写一个循环控制用户操作

        char key = ' ';
        Scanner sc = new Scanner(System.in);
        boolean loop = true;
        //输出一个菜单列表
        while (loop){
            System.out.println("s:  显示队列");
            System.out.println("e:  退出程序");
            System.out.println("a:  添加元素到队列");
            System.out.println("g:  从队列取出数据");
            System.out.println("h:  获取队列头的数据");
            key = sc.next().charAt(0);
            switch (key){
                case 's':
                    arrayQueue.showQueue();
                    break;

                case 'a':
                    System.out.println("输入你要添加的数");
                    int num = sc.nextInt();
                    arrayQueue.addQueue(num);
                    break;
                case 'g':
                    try {
                        System.out.println("取出数据为"+ arrayQueue.getQueue());
                    }catch (Exception e){
                        //TODO 处理异常
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    try {
                        System.out.println("该队列头数据为"+arrayQueue.peekQueue());
                    }catch (Exception e){
                        //TODO 处理异常
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    sc.close();
                    loop = false;
                    break;
            }
        }
        System.out.println("再见~~~");
    }
}

//使用数组模拟队列  编写一个类Queue
class ArrayQueue {
    private int maxSize;//表示数组的最大容量
    private int front;//头指针
    private int rear;//尾指针

    private int[] arr;//数组存放数据,完成队列结构

    //创建构造器
    //构造器中对队列进行初始化
    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        this.arr = new int[this.maxSize];
        //指向队列头部  分析指向队列头的前一个位置
        this.front = -1;
        //指向队列尾部  指向队列尾的数据(即包含队列最后一个数据)
        this.rear = -1;
    }

    //判断队列是否满
    public boolean isFull() {
        return rear == maxSize - 1;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return rear == front;
    }

    //添加数据(进队列)
    public void addQueue(int element) {
        if (isFull()) {
            System.out.println("队列满,不能加入数据");
            return;
        }
        rear++;
        arr[rear] = element;
    }

    //获取数据(出队列)
    public int getQueue() {
        if (isEmpty()) {
            //如果为空抛出异常
            throw new RuntimeException("队列空,不能获取数据");
        }
        front++;
        return arr[front];
    }

    //展示当前队列
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列空,无遍历内容");
        }
        for (int i = front + 1; i < rear+1; i++) {
            System.out.printf("arr[%d]=%d\t", i, arr[i]);
        }
    }

    //获取队列第一个元素,和出队列不同
    public int peekQueue() {
        if (isEmpty()) {
            //如果为空抛出异常
            throw new RuntimeException("队列空");
        }
        return arr[front + 1];
    }
}

问题分析

  1. 当前的数组使用一次之后就不能使用了
  2. 将这个数组使用算法搞成环形数列

优化成环形数组

思路如下:(这只是一种思路,也可以根据自己的思路进行、宗旨就是将数组头尾连接成为一个环形。)

  1. front变量的含义有所调整:front就指向队列的第一个元素,也就是说arr[front] 就是队列的第一个元素
  2. rear变量的含义:rear指向队列的最后一个元素的后一个位置。希望空出一个空间作为一个约定
  3. 当队列满时, (rear + 1) % maxSize == front
  4. 当队列空时,rear == front(与原先没有变化)。
  5. 当这样规定以后队列中有效的数字个数为(rear - front + maxSize) % maxSize
  6. 根据这个思路我们可以在这个基础上进行修改,得到环形队列。
  7. front和rear的初始值都是0。

代码实现

import java.util.Scanner;

//通过取模的方式实现环形列表
public class CircleQueueDemo {
    public static void main(String[] args) {
        System.out.println("-------测试数组完成环形队列的案例--------");
        //创建一个队列 这里设置最大大小为4但是实际使用大小为3
        CircleQueue circleQueue = new CircleQueue(4);
        // 写一个循环控制用户操作
        char key = ' ';
        Scanner sc = new Scanner(System.in);
        boolean loop = true;
        //输出一个菜单列表
        while (loop) {
            System.out.println("s:  显示队列");
            System.out.println("e:  退出程序");
            System.out.println("a:  添加元素到队列");
            System.out.println("g:  从队列取出数据");
            System.out.println("h:  获取队列头的数据");
            key = sc.next().charAt(0);
            switch (key) {
                case 's':
                    circleQueue.showQueue();
                    break;

                case 'a':
                    System.out.println("输入你要添加的数");
                    int num = sc.nextInt();
                    circleQueue.addQueue(num);
                    break;
                case 'g':
                    try {
                        System.out.println("取出数据为" + circleQueue.getQueue());
                    } catch (Exception e) {
                        //TODO 处理异常
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    try {
                        System.out.println("该队列头数据为" + circleQueue.peekQueue());
                    } catch (Exception e) {
                        //TODO 处理异常
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    sc.close();
                    loop = false;
                    break;
            }
        }
        System.out.println("再见~~~");
    }
}

class CircleQueue {
    private int maxSize;//表示数组的最大容量
    private int front;//头指针
    private int rear;//尾指针

    private int[] arr;//数组存放数据,完成队列结构

    public CircleQueue(int maxSize) {
        this.maxSize = maxSize;
        //todo 因为判断条件的改变这里在用户使用时传入的参数最好自行加1
        this.arr = new int[this.maxSize];
        //指向队列头部
        this.front = 0;
        //指向队列尾部  指向队列尾的数据  尾部的后面要空出一个空间作为约定
        this.rear = 0;
    }

    // 获取当前队列的有效元素个数。
    public int getSize() {
        return (rear - front + maxSize) % maxSize;
    }

    //判断队列是否满
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return rear == front;
    }

    //添加数据(进队列)
    public void addQueue(int element) {
        if (isFull()) {
            System.out.println("队列满,不能加入数据");
            return;
        }
        arr[rear] = element;
        //rear后移一位所以要考虑是否需要重头开始的问题。
        rear = (rear + 1) % maxSize;
    }

    //获取数据(出队列)
    public int getQueue() {
        if (isEmpty()) {
            //如果为空抛出异常
            throw new RuntimeException("队列空,不能获取数据");
        }
        // 这里需要分析出front指向的是第一个元素,
        // 先把front对应的值存放在临时变量中,
        // 然后将front后移动  后移的时候要考虑移动位置
        int res = arr[front];
        front = (front + 1) % maxSize;
        return res;//不需要将原来的位置置空,后期的数据直接覆盖了就行了。
    }

    //展示当前队列
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列空,无遍历内容");
        }
        //这一部分的遍历方式是肯定不对了
        //for (int i = front + 1; i < rear + 1; i++) {
        //    System.out.printf("arr[%d]=%d\t", i, arr[i]);
        //}
        // 先思考 从?开始遍历,遍历?个有效元素
        for (int i = front; i < front + getSize(); i++) {
            System.out.printf("arr[%d] = %d\t", i % maxSize, arr[i % maxSize]);
        }
        System.out.println();

    }

    //获取队列第一个元素,和出队列不同
    public int peekQueue() {
        if (isEmpty()) {
            //如果为空抛出异常
            throw new RuntimeException("队列空");
        }
        return arr[front];
    }
}

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

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

相关文章

【6月比赛合集】42场可报名的「创新应用」、「数据分析」和「程序设计」大奖赛,任君挑选!

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 创新应用赛&#xff08;39场比赛&#xff09;数据分析赛&…

MySQL—SQL优化详解(上)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

万物的算法日记|第三天

笔者自述&#xff1a; 一直有一个声音也一直能听到身边的大佬经常说&#xff0c;要把算法学习搞好&#xff0c;一定要重视平时的算法学习&#xff0c;虽然每天也在学算法&#xff0c;但是感觉自己一直在假装努力表面功夫骗了自己&#xff0c;没有规划好自己的算法学习和总结&am…

FasterTransformer 001 start up

FasterTransformer Faster Transformer是一个Transformer单层前向计算的高效实现。一个函数由多个OP组合实现。每一个基本OP都会对应一次GPU kernel的调用&#xff0c;和多次显存读写。OP融合可以降低GPU调度和显存读写&#xff0c;进而提升性能。在Faster Transformer&#x…

位姿估计 | 目标体坐标系相对于相机坐标系的位姿估计及其Python代码

目录 引言技术流程1. PNP介绍2. ICP介绍a. 利用ICP求解目标相对相机的位姿b. 利用ICP求解相机帧间运动 Python代码 引言 本文接着分享空间目标位姿跟踪和滤波算法中用到的一些常用内容&#xff0c;希望为后来者减少一些基础性内容的工作时间。以往分享总结见文章&#xff1a;位…

Redis 之Jedis 加springboot整合Redis

Jedis API 文档 在线文档: https://www.mklab.cn/onlineapi/jedis/ Jedis 介绍 Jedis 工作示意图 Java 程序操作Redis 的工具 示意图 Jedis 操作Redis 数据 快速入门 创建maven 项目 注意二步是路径配置自己想放哪里 三步是 定义包的层次结构 嫌弃麻烦的也可以不设置 …

chatgpt赋能python:Python编程技巧:如何横着打印差数列

Python编程技巧&#xff1a;如何横着打印差数列 随着互联网时代的到来&#xff0c;SEO已成为企业推广和营销的重要手段。而作为一名具有10年Python编程经验的工程师&#xff0c;我发现Python编程技巧的学习和应用也可以帮助企业优化SEO排名。本文将从实际项目需求出发&#xf…

如何实现Http请求报头的自动转发之设计

HeaderForwarder组件不仅能够从当前接收请求提取指定的HTTP报头&#xff0c;并自动将其添加到任何一个通过HttpClient发出的请求中&#xff0c;它同时也提供了一种基于Context/ContextScope的编程模式是我们可以很方便地将任何报头添加到指定范围内的所有由HttpClient发出的请求…

基于Java家政服务网站系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

opencv人与摄像头距离、角度检测

参考&#xff1a; https://chtseng.wordpress.com/2018/09/18/%E5%A6%82%E4%BD%95%E4%BC%B0%E7%AE%97%E5%89%8D%E6%96%B9%E4%BA%BA%E7%89%A9%E7%9A%84%E8%B7%9D%E9%9B%A2/ WeChat_20230611160620 1、cv2加载摄像头慢解决方法&#xff0c;单独重新cv2.VideoCapture() https://b…

新《终结者》电影剧本或交由 ChatGPT 书写

据外媒报道&#xff0c;詹姆斯・卡梅隆透露他正在创作下一部《终结者》电影的剧本&#xff0c;他同时表示新剧本的灵感得益于 OpenAI 的 ChatGPT。 打开豆瓣&#xff0c;1984年10月上映的那部「终结者」评分依然在8分以上。而后&#xff0c;终结者系列的电影不断上新&#xff…

基于Java房屋租售网站设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

考研计算机组成思维导图总结(408,833,834)

需要思维导图文件和图片的可以去我的Github上寻找&#xff0c;这份思维导图参考23年王道机组&#xff0c;同时添加了一部分833&#xff0c;834需要知识点。 注意&#xff1a;最后的机组知识点仍要以学院进行对照&#xff0c;这里只是提供参考 思维导图pdf和知识点图片 文章目…

<Linux> 《SUSE Linux 中SSH安全加固》

《SUSE Linux 中SSH安全加固》 1 说明2 安全加固2.1 更改 ssh 默认端口2.2 限制 ROOT 远程登陆2.3 修改默认登录时间2.4 升级旧版本2.5 当用户处于非活动时断线2.6 修改加密协议版本2.7 限制 IP 登录2.8 允许或禁止指定用户和组登录2.9 限制监听 IP2.10 最后修改配置文件的属性…

【JVM 监控工具】JVisualVM的使用

文章目录 前言二、启动JVisualVM三、安装插件四、使用 前言 JVisualVM是一个Java虚拟机的监控工具&#xff0c;要是需要对JVM的性能进行监控可以使用这个工具哦 使用这个工具&#xff0c;你就可以监控到java虚拟机的gc过程了 那么&#xff0c;这么强大的工具怎么下载呢&…

【HBZ分享】FactoryBean的应用 与 BeanFactroyPostProcessor的应用 与 BeanPostProcesser的应用

FactoryBean的应用实战 需要写一个A类来实现FactoryBean实现FactoryBean的3个方法&#xff0c;即getOject(), getObjectType(), isSingleton()注意&#xff1a;在通过xml的【 】标签或者通过注解方式将A类注入容器的时候&#xff0c;返回的实例不是A类&#xff0c;而是T类&…

HTML 基础

目录 HTML 结构 1.认识 HTML 标签 HTML 文件基本结构 标签层次结构 HTML 常见标签 注释标签 标题标签: h1-h6 段落标签: p 换行标签: br 格式化标签 图片标签: img 关于目录结构: 超链接标签: a 链接的几种形式: 表格标签 合并单元格 列表标签 表单标签 form …

【头歌-Python】Python第九章作业(初级)第 1、2、4 关

第1关&#xff1a;绘制温度曲线 任务描述 附件中是某月每天的最高温度和最低温度数据&#xff0c;请绘制本月的高温曲线&#xff08;红色、圆点标记坐标&#xff09;和低温曲线&#xff08;蓝色、星号标记坐标&#xff09;&#xff0c;线型、刻度如输出示例所示&#xff0c;线…

Rust每日一练(Leetday0031) 解码方法、复原 IP 地址

目录 91. 解码方法 Decode Ways &#x1f31f;&#x1f31f; 93. 复原 IP 地址 Restore IP Addresses &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 91. …