数据结构小白之队列与环形队列的模拟

2023-11-12

队列的简单介绍:

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

使用数组来模拟队列

  1. 说明
  2. 实现思路
  3. 示意图
  4. 代码
1.说明

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

*由于队列的输入输出分别从前后端来处理,所以需要两个变量front和rear分别记录队列的前后端的下标,front随着数据输出而改变(向上移动),rear随着数据的输入而改变(向上移动)

2.实现思路

将数据存储队列时,将尾指针向后移动,rear+1,将数据输出的时候,front+1进行数据输出,当front==rear(队列空)。

若尾指针rear小于队列的最大下标maxSize-1,则将队列存入rear所指的数组元素中,否则无法存入数据,rear==maxSize-1(队列满)。

3.示意图

在这里插入图片描述

4.代码:

1.建立类和构造器

class ArrayQueue {
    private int maxSize;//数组的最大容量
    private int front;  //指向队列头指针
    private int rear;   //指向队列尾指针
    private int[] arr;   //该数组用于存放数据

    //创建队列的构造器
    public ArrayQueue(int arrMaxSize) {
        maxSize = arrMaxSize;
        arr = new int[maxSize];
        front = -1;//指向队列头部,此时指向队列头的前一个位置
        rear = -1;//指向队列的尾部,此时指向队列的最后一个位置
    }

2.判断队列是否为空或者为满

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

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

3.入队列

//添加数据
public void addQueue(int n) {
    //判断队列是否满
    if (isFull()) {
        System.out.println("队列已满,不能加入数据");
        return;
    }
    rear++;//加入数据 尾指针后移
    arr[rear] = n;
}

4.出队列

//出队列(获取队列数据)
public int getQueue() {
    if (isEmpty()) {
        throw new RuntimeException("队列已空,不能取出数据");
    }
    front++;

    return arr[front];
}

5.显示队列以及队列的头数据

//显示队列
public void showQueue() {
    if (isEmpty()) {
        System.out.println("队列为空,没有数据");
        return;
    }
    //printf用来进行输入各种占位符
    for(int i=0;i<arr.length;i++){
        System.out.printf("arr[%d]=%d\n",i,arr[i]);
    }
}

//显示队列的头数据
public int headQueue() {
    if (isEmpty()) {
        throw new RuntimeException("队列为空");
    }
    return arr[front + 1];
}

6.主函数测试

public static void main(String[] args) {
    //创建一个队列
    ArrayQueue arrayQueue = 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':
                arrayQueue.showQueue();
                break;
            case 'a':
                System.out.println("请输入一个数据:");
                int value=scanner.nextInt();
                arrayQueue.addQueue(value);
                break;
            case 'g':
                try {
                    int res=arrayQueue.getQueue();
                    System.out.printf("取出的数据是%d\n",res);
                }catch (Exception e){
                    System.out.println(e.getMessage());
                }
                break;

            case 'h':
               try {
                   int res=arrayQueue.headQueue();
                   System.out.printf("队列头的数据是%d\n",res);
               }catch (Exception e){
                   System.out.println(e.getMessage());
               }
                break;
            case 'e':
                scanner.close();
                loop=false;
                break;
        }
    }
    System.out.println("程序退出");
}
注意:由于使用数组去模拟普通队列,只能使用一次,所以需要将普通队列改进为环形队列

数组模拟环形队列

思路如下:
1.front变量的含义做一个调整:front就指向数组队列的第一个元素(原先指向第一个元素的前一个位置),也就是说arr[front]是队列的第一个元素

2.rear指向队列的最后一个元素的后一个位置(原先指向最后一个元素),因为希望空出一个空间做一个约定

3.当队列满时,条件时(rear+1)%maxSize=front【首尾是否重合】

4.队列为空时,rear==front

5.front的初始值为0.rear的初始值为0

6.队列中有效的个数 (rear+maxSize-front)%maxSize

测试一下:
在这里插入图片描述

因此可以修改上述代码如下:

package com.lz.arrayqueue;

import java.util.Scanner;

/***
 * 环形数组实现队列的多次使用
 */
public class CircleArrayQueue {
//测试函数
    public static void main(String[] args) {
        //创建一个队列
        System.out.println("测试数组模拟环形队列的案例~");
        //最大有效数据为3(0--2)
        CircleArray arrayQueue = new CircleArray(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':
                    arrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.println("请输入一个数据:");
                    int value = scanner.nextInt();
                    arrayQueue.addQueue(value);
                    break;
                case 'g':
                    try {
                        int res = arrayQueue.getQueue();
                        System.out.printf("取出的数据是%d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;

                case 'h':
                    try {
                        int res = arrayQueue.headQueue();
                        System.out.printf("队列头的数据是%d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
            }
        }
        System.out.println("程序退出");
    }

}

//编写一个CircleArray的类
class CircleArray {
    private int maxSize;//数组的最大容量
    private int front;  //指向队列头指针 指向首部 初始值为0
    private int rear;   //指向队列尾指针 指向尾部后一个位置 初始值为0
    private int[] arr;   //该数组用于存放数据

    //创建队列的构造器
    public CircleArray(int arrMaxSize) {
        maxSize = arrMaxSize;
        arr = new int[maxSize];
        front = 0;
        rear = 0;
    }

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

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

    //添加数据
    public void addQueue(int n) {
        //判断队列是否满
        if (isFull()) {
            System.out.println("队列已满,不能加入数据");
            return;
        }
        arr[rear] = n;//因为rear已经指向了后一个位置
        rear = (rear + 1) % maxSize;//为了考虑前面的位置【循环使用】
    }

    //出队列(获取队列数据)
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列已空,不能取出数据");
        }
        //front是指向队列的第一个元素
        //1.先把front对应的值保存到一个临时变量 然后将front后移
        int value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }

    //显示队列
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空,没有数据");
            return;
        }
        //printf用来进行输入各种占位符
        //从front开始遍历 遍历多少个元素 当前有效元素:(rear+maxSize-front)%maxSize
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
        }
    }

    //求出当前队列的有效数据
    public int size() {
        return (rear + maxSize - front) % maxSize;
    }

    //显示队列的头数据
    public int headQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }
        return arr[front];
    }
}





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构小白之队列与环形队列的模拟 的相关文章

  • 以OpenGL/ES视角介绍gfx-hal(Vulkan) Shader/Program接口使用

    文档列表见 Rust 移动端跨平台复杂图形渲染项目开发系列总结 目录 背景 The right way to tackle this in Vulkan is to use resource descriptors A descriptor
  • 50个c/c++源代码网站

    C C 是最主要的编程语言 这里列出了50名优秀网站和网页清单 这些网站提供c c 源代码 这份清单提供了源代码的链接以及它们的小说明 我已尽力包括最佳的C C 源代码的网站 这不是一个完整的清单 您有建议可以联系我 我将欢迎您的建 议 以
  • netty handler的执行顺序(3)

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 今天解决2个问题 1 handler在pipeline当中究竟是如何存储的 2 在遍历handler的过程中 会根据event的不同 调用不同的handler 这一点是如何
  • 树06--二叉树中和为某一值的路径

    树06 二叉树中和为某一值的路径 jz24 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 输入一颗二叉树的根节点和一个整数 按字典序打印出二叉树中结点值的和为输入整数的所有路径 路径定义为从树的根结点开始往下一直到叶结点所经
  • Sort List

    Sort a linked list in O n log n time using constant space complexity 题目要求用 O n log n 的时间复杂度和常数的空间复杂度来进行链表排序 O nlogn 的排序算
  • 4399 C++笔试题

    1 写出一个函数 取到链表中倒数第二个节点 双链表 node getSec List mylist return mylist m tail gt m prev m prev为链表前指针 单链表 node getSec List mylis
  • 数据结构----链式栈

    目录 前言 链式栈 操作方式 1 存储结构 2 初始化 3 创建节点 4 判断是否满栈 5 判断是否空栈 6 入栈 7 出栈 8 获取栈顶元素 9 遍历栈 10 清空栈 完整代码 前言 前面我们学习过了数组栈的相关方法 链接 线性表 栈 栈
  • 链表和线性表的优缺点

    链表和线性表的优缺点 作为我们最先接触的两个数据结构 链表和线性表的优缺点都较为明显 并且二者互相补足 文章目录 链表和线性表的优缺点 线性表 线性表的组成 线性表的缺点 线性表的优点 链表 链表的组成 链表的优点 链表的缺点 总结 线性表
  • DDP入门

    DDP 即动态动态规划 可以用于解决一类带修改的DP问题 我们从一个比较简单的东西入手 最大子段和 带修改的最大子段和其实是常规问题了 经典的解决方法是用线段树维护从左 右开始的最大子段和和区间最大子段和 然后进行合并 现在我们换一种方法来
  • DNG格式解析

    Author Maddock Date 2015 04 22 转载请注明出处 http www cnblogs com adong7639 p 4446828 html DNG格式基本概念 DNG格式是在TIFF的基础上扩展出来的 要了解D
  • Hash映射理解

    先说数组 数组优点之一 能通过索引很快定位到值 hashmap 就是利用了数组这个优点 对比 线性映射 定义一个数组 数组的元素是结构体 结构体包括 一对键 值 伪代码表示 a 0 struct Bill 5 a 1 struct KK 6
  • Python 实现列队

    1 列队定义 队列是项的有序结合 其中添加新项的一端称为队尾 移除项的一端称为队首 当一个元素从队尾进入队列时 一直向队首移动 直到它成为下一个需要移除的元素为止 最近添加的元素必须在队尾等待 集合中存活时间最长的元素在队首 这种排序成为
  • JavaScript系列——数组元素左右移动N位算法实现

    引言 在自己刚刚毕业不久的时候 去了一家公司面试 面试官现场考了我这道题 我记忆深刻 当时没有想到思路 毫无疑问被面试官当成菜鸟了 最近刚好在研究数组的各种算法实现 就想到这道题 可以拿来实现一下 纪念自己逝去的青春 需求 假设有这样一个数
  • 数据结构——计算节点个数和二叉树高度(C语言版)

    摘自 数据结构 计算节点个数和二叉树高度 C语言版 作者 正弦定理 发布时间 2020 12 12 23 27 09 网址 https blog csdn net chinesekobe article details 111086664
  • 堆栈01--用两个栈实现队列

    堆栈01 用两个栈实现队列 jz05 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 用两个栈来实现一个队列 完成队列的Push和Pop操作 队列中的元素为int类型 测试用例 队列先进先出 输入 1 2 输出 1 2 解析
  • 浮生六记

    浮生六记 目录 浮生六记卷一 闺房记乐 002 浮生六记卷二 闲情记趣 015 浮生六记卷三 坎坷记愁 022 浮生六记卷四 浪游记快 034 浮生六记 2 浮生六记卷一 闺房记乐 余生乾隆癸未冬十一月二十有二日 正值太平盛世 且在 衣冠之
  • 数理统计知识整理——回归分析与方差分析

    题记 时值我的北科研究生第一年下 选学 统计优化 课程 备考促学 成此笔记 以谨记 1 线性回归 1 1 原理分析 要研究最大积雪深度x与灌溉面积y之间的关系 测试得到近10年的数据如下表 使用线性回归的方法可以估计x与y之间的线性关系 线
  • 雪糕的最大数量 排序+贪心

    雪糕的最大数量 雪糕的最大数量 题目描述 样例 数据范围 思路 代码 题目描述 夏日炎炎 小男孩 Tony 想买一些雪糕消消暑 商店中新到 n 支雪糕 用长度为 n 的数组 costs 表示雪糕的定价 其中 costs i 表示第 i 支雪
  • Leetcode2661. 找出叠涂元素

    Every day a Leetcode 题目来源 2661 找出叠涂元素 解法1 哈希 题目很绕 理解题意后就很简单 由于矩阵 mat 中每一个元素都不同 并且都在数组 arr 中 所以首先我们用一个哈希表 hash 来存储 mat 中每
  • 【数据结构入门精讲 | 第二篇】一文讲清算法复杂度

    上篇文章中我们引入了算法 数据结构 数据类型等概念 而要想衡量一个算法与数据结构是否为优质的 就需要一个衡量标准 这个衡量标准也是在我们实现一个好的算法时要遵循的原则 目录 基本概念 渐进性态 渐进性态数学表征 算法复杂度的运算 顺序搜索算

随机推荐

  • mvp关联activity生命周期_Android MVP架构从入门到精通-真枪实弹

    Android MVP架构从入门到精通 真枪实弹 一 前言 你是否遇到过Activity Fragment中成百上千行代码 完全无法维护 看着头疼 你是否遇到过因后台接口还未写而你不能先写代码逻辑的情况 你是否遇到过用MVC架构写的项目进行
  • VMware Workstation 16 Player 安装Centos 7

    环境准备 VMware Workstation 16 Player 官方下载 https www vmware com products workstation player workstation player evaluation ht
  • Cesium 源码解析 Model(一)

    Cesium中对于3DTiles会解析成Model 特别是3DTile中的B3DM 过程主要是对gltf在Cesium中是如何解析并生成绘制命令的 content model new Model gltf gltfView gltf数据 c
  • 全球数字治理白皮书 附下载

    当今世界 科技革命和产业变革日新月异 数字经济蓬勃发展 深刻改变着人类生产生活方式 对各国经济社会发展 全球治理体系 人类文明进程影响深远 在经济全球化遭遇逆流 保护主义 单边主 义上升的背景下 数字化驱动的新一轮全球化仍蓬勃发展 已成为助
  • QT学习笔记(七)

    第12章 输入与输出 Qt提供了读写字节块的设备类QIODevice QIODevice类是抽象的 无法被实例化 一般是使用它的子类 它包括如下子类 其中 QProcess QTcpSocket QUdpSocket QSslSocket都
  • Java 优先级队列

    文章目录 Java 优先级队列 PriorityQueue简介 继承关系 PriorityQueue示例 Comparable比较器 Comparable接口 Comparator比较器 Comparator接口 底层原理 Java 优先级
  • Unity3d 游戏优化 mono等

    GC问题 1 C 变量分为两种类型 值类型和引用类型 值类型分配在栈区 引用类型分配在堆区 GC关注引用类型 2 GC卡顿原因 堆内存垃圾回收 向系统申请新的堆内存 3 GC触发条件 堆内存分配而当内存不足时 按频率自动触发 手动强行触发
  • 【Vue】 前端上传图片时限制只可以按文件夹上传图片( webkitdirectory )

    前言 最近再对公司前后端不分离的 C Winform 系统进行 Java Web 重构 为了保持客户使用习惯所以要高度还原 其中有一个功能就是上传图片时 以文件夹进行上传 要读取文件夹内所有的图片 看了挺多大神的博客 也看了 Element
  • Keepalived与HaProxy的协调合作原理分析

    Keepalived与HaProxy的协调合作原理分析 keepalived与haproxy合作场景 更好的理解方式 协调合作中考虑的问题 一 Keepalived 以TCP IP模型角度来分析 二 HaProxy 总结 协调合作中考虑的问
  • Go-Python-Java-C-LeetCode高分解法-第四周合集

    前言 本题解Go语言部分基于 LeetCode Go 其他部分基于本人实践学习 个人题解GitHub连接 LeetCode Go Python Java C Go Python Java C LeetCode高分解法 第一周合集 Go Py
  • 由于找不到d3dx9_43.dll无法继续执行-修复教程

    d3dx9 43 dll是一个非常重要的DLL文件 它属于微软DirectX 9 0c的一部分 它主要用于游戏应用程序的开发和运行 在使用Windows平台的玩家中非常常见 这个文件通过DirectX接口提供了一些相关的功能 比如图像和声音
  • 该服务器因不稳定无法正常反应,服务器连接异常

    服务器连接异常 内容精选 换一换 ELB的常见异常返回码有400 403 502 504等 若遇到这些返回码建议您先直接访问后端云服务器 查看是否是后端云服务器的异常 若后端云服务器响应正常 请参考表1排查处理 如果仍无法解决 请联系客服人
  • 非关系型数据库、关系型数据库mysql简介

    Nosql 非关系数据库 数据存储不需要固定的模式 NoSql特点 易扩展 数据之间无关系 大数据量高性能 细粒度 cache性能高 多样灵活的数据模型 增删字段容易 关系数据库 vs NoSql 传统关系数据库 ACID 事务所具有的四个
  • 【华为OD机试】组成最大数 (C++ Python Java)2023 B卷

    题目描述 小组中每位都有一张卡片 卡片上是6位内的正整数 将卡片连起来可以组成多种数字 计算组成的最大数字 输入描述 号分割的多个正整数字符串 不需要考虑非数字异常情况 小组最多25个人 输出描述 最大的数字字符串 用例1 输入 22 22
  • 机械电子工程用不用学c语言,机械电子工程到底学什么 毕业以后能干什么

    机械电子工程专业俗称机电一体化 是机械工程与自动化的一种 下文有途网小编给大家整理了机械电子工程的就业方向及前景 供参考 机械电子工程专业主要学什么 机械电子工程要学习得课程有 电工与电子技术 机械制图 工程力学 机械设计基础 机械制造基础
  • 红队打靶,红日系列,红日靶场5

    文章目录 靶场详情 外网渗透 端口扫描 漏洞发现与利用 获取shell 内网渗透 提权 内网信息收集 横向移动 第一种使用CS 第二种使用msf 路由转发与代理通道 Psexec 攻击 靶场详情 此次靶场虚拟机共用两个 一个外网一个内网 用
  • java实现二分查找-两种方式

    二分查找是一种查询效率非常高的查找算法 又称折半查找 起初在数据结构中学习递归时实现二分查找 实际上不用递归也可以实现 毕竟递归是需要开辟额外的空间的来辅助查询 本文就介绍两种方法 二分查找算法思想 有序的序列 每次都是以序列的中间位置的数
  • 看融合数学教学的steam教育模式

    传统意义上的 教育 德育 教学双肩挑 是要求教师能够处理好 德育 和 教学 两方面的工作要求 这实质上是通过人为划分的两个途径实现对学生的培养 STEAM教育的跨学科整合思维能够很好的迁移在 德育 与 教学 的整合上 即在教师引导下的学生参
  • OWASP Top 10 2021 榜单出炉,安全人员必看

    作为一个安全人员 如果你还不知道OWASP Top 10是什么 那么请你接着往下看 OWASP 开放式Web应用程序安全项目 是一个开源的 非营利性的全球性安全组织 致力于改进Web应用程序的安全 这个组织最出名是 它总结了10种最严重的W
  • 数据结构小白之队列与环形队列的模拟

    队列的简单介绍 队列是一个有序列表 可以使用数组或者链表来实现 队列遵循先入先出的原则 先存入队列的数据要先取出 后存入的后取出 使用数组来模拟队列 说明 实现思路 示意图 代码 1 说明 队列本身是有序列表 若使用数组的结构来存储队列的数