数组队列——循环队列

数据结构——循环队列详解 队列主要有顺序队列,循环队列,双端队列,优先队列。而当中循环队列是一种线性数据结构。它也被称为“环形缓冲器”。它只允许在一端进行插入操作,即队尾(rear),而在另一端进行删除操作,即队头 (front),其操作表现基于FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。向队列中插入新的数据元素称为入队,新入队的元素就成为了队列的队尾元素。循环队列允许元素在队尾插入,在队头删除,同时遵循先进先出原则。由于循环队列是基于数组实现的,所以它的访问速度很快,特别是在移动元素时。 阅读详情

目录

1.数组队列的基本概念

2.代码实现

3.数组队列的不足

4.循环队列的基本概念

5.代码实现

6.总结


一.数组队列的基本概念

        队列是一种线性的数据结构,其特点是先进先出;像排着一条队伍进房间,先排队则优先进入房间,想要排队必须从队尾开始排。

        如图所示:

二.数组队列的代码实现

根据这个特点,以数组为存储容器,来模拟数组队列。

        1.首先要确定队列大小(数组大小),设置最大容量:int MaxSize;

        2.接着要实现队列的功能,需要设置两个变量来记录对头和队尾的下标;

                int  front = -1;        //记录队头的下表

                int rear = -1;          //记录队尾的下表

        3.队列有三种情况

               (1) 当队列中没元素时我们规定第一个元素的前一个是front。

                        并且         front == rear ;

               (2) 当队列满时最后一个元素的前一个为rear。

                        即             rear == MaxSize - 1;

所以判断队列是否满和空的代码如下:

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


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

队列为空的情况:                                                                队列满的情况:

只要rear == front ,队列便是空的,不一定要如上图。

特别说明:因为队列满时满足:rear = MaxSize -1; 而不管front处于什么位置,所以普通队列存在一个问题,数组队列只能用一次,当队列满后便无法复用。

                (3)队列有空间且不为空时。

                        我们有两种功能,往队列中存数据,从队列中取数据。

                        存数组:从队尾加入一个数,并且队尾标志rear向后移动一位:rear++;

                        取数据:从对头取出一个数,并且对头标志front向后移动一位:front++;

    //进对列存数据
    public void addArr(char n){
        if (isFull()){
            System.out.println("队列满不能加入数据");
            return;
        }
        rear++;
        arr[rear] = n;
    }


    //获取队列的数据,出队列
    public char getQueue(){
        if (isEmpty()){
            throw new RuntimeException("数组为空,不能取数据");
        }
        front++;
        return arr[front];
    }

进队如图:

注意:是先进行rear++,再让数据进队arr[rear] = value,所以当判满时条件仍然是: rear == MaxSize - 1;

出队如图:

只要出队一次,便front++,同样是是先进行front++,再让数据出队arr[front] = value;

        4.其他的一些功能的代码。

                打印数组队列,便按照数组规则遍历;取头元素,便通过arr[front+1]来看,注意是只查看不取出来。

    //打印队列中的数据
    public void showQueue(){
        if (isEmpty()){
            System.out.println("队列空没有数据");
            return;
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.printf("arr[%d]=%c\n",i,arr[i]);
        }
    }
    
    //显示头数据
    public char headQueue(){
        if (isEmpty()){
            System.out.println("队列空没有数据");
        }
        return arr[front+1];
    }

三.数组队列的局限和不足

        上述特别说明中提到,当队列存满,便再也不能存数据。因此数组队列是一个一次性的存储结构。

        因此引出一个优化的列表形式:循环列表。

四.循环队列的基本概念

        1.首先,循环队列是只将队列首尾相接像一个环(实际上是通过取模的方式,让front和rear小于maxSize);但同样遵循先进先出,从队尾进队,从对头出队的原则

        2.其次我们规定需要的变量:

                确定循环队列容量:int maxSize;

                空时队首:int front = 0;  队尾:rear= 0             //这次front代表头元素的数组下标。

                满时队尾:int rear = maxSize +1      //rear代表最后一个元素的后一位,所以有一个空位

        如图:

五.循环队列代码实现

        1.判断队列空和满

        队列依旧是数组队列,但实现循环,是通过对取模的方式防止数组越界,这样即使队列满了,只要出队取数据又可以存新的数据。

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

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

        2.往队列存数据

        

下一次再存会先判断队列是否满,条件是 (rear+1)%maxSize == front;因此如图,当rear==6时队列已经满了,所以循环队列会预留一个空间。

代码如下:

        取模操作同样是为了防止数组越界。

    //添加数据到队列
    public void addQueue(char n){
        if (isFull()){
            System.out.println("队列满,不能加入数据");
            return;
        }
        //将要添加的数据存入队列数组
        arr[rear] = n;
        //将rear后移,这里必须考虑取模
        rear = (rear + 1)%maxSize;
    }

        4.出队取数据

代码如下

    //获取队列数据,出队列
    public char getQueue(){
        if (isEmpty()){
            throw new RuntimeException("队列空,不能取数据");
        }
        //front移动位置,要做取模处理,防止数组越界
        //1.先把front指向队列的第一个元素
        //2.将front对应的值保留到一个临时变量
        //3.将临时保存的变量返回
        int value = arr[front];
        front = (front + 1)%maxSize;
        return value;
    }

看看此时循环队列的优势出现了,现在再判断队列,此时(rear+1)%maxSize != front,所以可以接着存数据,直到再次满为止。

3.其他功能代码:

        因为是循环队列,所以遍历从对头开始,遍历条件是front + 队列中存储数据的个数。

 即front + (rear+maxSize-front)%maxSize;

    //打印队列所以数据
    public void showQueue(){
        if (isEmpty()){
            System.out.println("队列为空,没有数据");
            return;
        }
        //从队首开始
        for (int i = front; i < front+size(); i++) {
            //因为是循环数组,下标要考虑取模
            System.out.printf("arr[%d]=%c\n",(i%maxSize),arr[i%maxSize]);
        }
    }

    //获取队列有效数值长度
    public int size() {
        return (rear+maxSize-front)%maxSize;
    }

    //显示队列的头元素
    public int headQueue(){
        if (isEmpty()){
            System.out.println("队列空没有数据");
        }
        return arr[front];
    }

六.总结

        首先要明确队列的特点,先进先出,对头出队,队尾进队。其次通过数组对列探究对列的特性中设置了许多表示下标的变量,通过移动变量位置来实现入队出队;但实际上数组的值还是存在,只不过获取数据是通过arr[front]来获取。

        在研究普通数组队列时我们发现一旦队列满就再也无法存储数据的问题,因此出现了循环队列,通过取模来防止数组越界以此重复利用数组,只要出队取数据,保证数组队列中有空间,便可再次存数据,因此解决了这个问题。

【数据结构】循环队列 队列又称为"先进先出(FIFO)"线性表:插入操作只能在队尾进行,删除操作只能在队首进行。而循环队列是队列的一种特殊形式,循环队列(也被称为环形队列)是一种线性数据结构,其操作表现基于先进先出原则,并且队尾被连接在队首之后以形成一个循环。循环队列固定大小,空间能够重复利用。循环队列可以用数组或者链表实现,那下面我们来分析一下哪种方式更好:当我们想使用链表实现时,假设我们想要开辟的队列长度为k = 4;front表示队头指针,rear表示队尾指针:由上图可知,当rear和front 都指向同一个位置时队列为空 阅读详情

相关推荐

Leetcode:662.Design Circular Queue 设计循环队列

Design Circular Queue 设计循环队列 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存...

Coding 1209

循环队列详解

简单易懂的循环队列

weixin_55858644的博客 4万+

循环队列拾遗-使用数组实现循环队列

循环队列为充分利用向量空间,克服”假溢出”现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。这种循环队列可以以单链表的方式来在实际编程应用中来实现。循环队列的问题循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列

Sha0w的博客 6069

【数据结构】队列——循环队列(详解)

0 循环队列循环队列(Circular Queue)是队列的一种实现方式,它通过将队列存储空间的最后一个位置与第一个位置相连接,形成一个循环的队列结构,从而可以更加高效地利用存储空间。在循环队列中,当队尾指针到达队列存储空间的末尾时,下一个插入操作将从头开始,即实现了队列的“循环”。1 特定条件下循环队列队/空队满判断条件在循环队列中,判断队列是否为空或已满是一个重要的操作。由于循环队列的特性,我们不能简单地通过比较队头指针(front)和队尾指针(rear。

2201_75425839的博客 1万+

整理笔记——二极管

二极管是一种由半导体材料制成的一种具有单向导电性能的电子元器件,二极管的核心是PN结。加在二极管两端的电压和通关的电流被成为,二极管的伏安特性曲线​​​二极管的正向特性:起初正向电压较小时,正向电流几乎没有,称之为死区,此时二极管处于截止状态。当电压差超过截止电压(0.5V或者0.7V),电流随着电压上升,开始增加缓慢,随后急剧增大,二极管的电阻变小进入导通状态,此时电压变化较小。二极管的反向特性:起初反向电流很小,不随电压二变化,此时成为反向饱和电流;当方向电压达到二极管的反向击穿电压。

#include 811

内网CentOS离线部署LibreOffice:从依赖缺失到服务启动的完整避坑指南

本文详细介绍了在CentOS内网环境中离线部署LibreOffice的完整流程,包括依赖包准备、安装顺序优化及常见报错解决方案。针对金融等封闭网络场景,提供从rpm包选择到服务启动的全套避坑指南,特别解决libXinerama等图形库缺失问题,确保文档转换服务稳定运行。

weixin_33416697的博客 246

数组队列及循环队列

java数据结构之----数组队列及循环队列 数据结构与算法学习的第二篇 什么时候需要用到队列 队列在实际开发过程中运用的非常广泛,由于我也是学习基础,还没有开发过什么项目,所以用到时候就知道了 什么是队列 队列是一个有序列表,可以用数组或者链表来实现 队列遵守先入先出的原则 联系实际场景 可以把一个队列的存入,读取数据的过程看成在银行里面排队办理业务,进银行,取号,叫号,办理业务,出银行...

一个猿子的博客 670

【项目实战】基于STM32单片机的智能小车设计(有代码)

【1】背景意义 近些年随着国民生活水平的提升,以小车为载体的轮式机器人进入了我们的生活,尤其是在一些布线复杂困难的安全生活区和需要监控的施工作业场合都必须依赖轮式机器人的视频监控技术。因此,基于嵌入式技术的无线通信视频监控轮式机器人应运而生。由于它们与人类工作相比具有成本低廉、安全稳定的优点,目前已经在许多危险作业以及工业场合得到了广泛应用而且轮式机器人不需要像人那样采取过多的保护措施,因此轮式机...

ShawnWang1994的博客 13万+

使用数组实现循环队列

为了节省空间,这里使用数组实现了更加实用 的循环队列,代码主体和上一篇大多一样,但是涉及到一些细节。 下面是具体的思路: 上一篇中front表示第一个元素前面的位置,rear表示最后一个元素的位置, 但是,在这里由上图可知,front和rear的含义发生了调整。 牺牲一个空间,来提高的代码的可礼节性,这样的循环队列比maxSize上存储一个元素,但是无大碍。 这里面的一个重点就是循环队列的实际有效...

大道至简 3009

VMware Workstation Pro 17 最新破解版安装教程(附永久激活密钥)

本文详细介绍了VMware Workstation Pro 17专业版的安装与配置指南,包括系统要求检查、官方版本安装流程、高级配置优化及常见问题排查。通过合规使用官方版本,开发者可以充分利用其强大的虚拟化能力,提升多平台开发与测试效率。

weixin_29327977的博客 3552

USB-Blaster在Win11报错?3分钟搞定驱动兼容性问题(Quartus 21.4实测)

本文针对Windows 11系统下USB-Blaster驱动安装问题,提供了一套快速解决方案。通过优化驱动安装流程、绕过签名验证及设备管理器高级技巧,帮助开发者在3分钟内解决Quartus 21.4的兼容性问题,提升FPGA调试效率。

weixin_30772105的博客 291

数组存放循环队列

/*以数组存放循环队列,tag=0或1区分rear和front相等时 队空或者队满,编写相应的入队和出队算法。 */ #ifndef PCH_H #define PCH_H #include<stdio.h> #include<iostream> #include<malloc.h> #include<cstdlib>//包含exit头文件 #inc...

SuiGi的博客 2021

获取iOS设备唯一标识UUID(Swift版)

属性返回的UUID是与应用程序相关联的,也就是说,如果用户卸载并重新安装应用程序,该UUID可能会发生变化。如果您需要一个与设备相关的持久唯一标识符,您可以考虑使用Keychain或其他方法来存储和检索设备标识符。在iOS开发中,我们经常需要获取设备的唯一标识符来进行一些特定的操作,比如设备识别、数据追踪等。在本文中,我将向您展示如何使用Swift编程语言获取iOS设备的唯一标识UUID。通过上述代码,您可以在您的iOS应用程序中轻松获取设备的唯一标识符。属性来获取设备的唯一标识UUID。

BitNetO的博客 1918

详解循环队列——链表与数组双版本

循环队列, 本篇将会讲述链表, 数组双版本。

strive_mianyang的博客 3266

Gazebo手册:【1】gazebo基本操作案例

欢迎来到初学者模块!本模块将引导您了解 Gazebo 的最基本功能。我们将构建一个简单的车辆来演示这些功能。这些教程适用于 Gazebo 新手和/或没有编程或 Linux 经验的人。 每个教程都建立在上一个教程的基础上,因此我们建议您按顺序学习这些教程。 一、何为Gazebo? Gazebo 是一款 3D 动态模拟器,能够准确有效地模拟复杂室内和室外环境中的机器人种群。虽然类似于游戏引擎,但 Gazebo 提供了更高保真度的物理模拟、一套传感器以及用于用户和程序的接口。 1............

gongdiwudu的专栏 2万+

【AI测试必学】DeepSeek API 快速入门:获取 API Key 与调用 API 步骤详解

DeepSeek API 使用与 OpenAI 兼容的格式,可以通过修改配置使用 OpenAI SDK。生成的 API Key 只会显示一次,请妥善保存。注册并登录账号,进入左侧导航栏的。创建 API Key。

blues_C的博客 1万+

用数组实现循环队列

<br />      若用数组实现队列一般会整成循环队列,要不队列没法用~~~实现的功能包括创建队列、入队列、出队列、读队列头~~~~~~~<br />/************************************************************************/ /* author : thomas E-mail: chenhua308@gmail.com */ /******

Thomas chen的专栏 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【数据结构】数组循环队列的实现

队列只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。假设当前队列分配的空间最大为6,则当队列处于上图的最后一个状态时,就不可以在继续插入新的队尾元素,否则会出现溢出的情况,即因数组越界而导致程序的非法操作错误。队列的实现方式有多种,包括基于数组的静态队列、基于链表的动态队列等。操作受限:队列只允许在队尾插入元素(入队),在队头删除元素(出队),其他位置的元素无法直接访问或修改。那么怎么解决这个问题呢?

2303_80187476的博客 2189

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

用数组模拟循环队列

设计一种循环队列,线性数据结构,其操作表现为 FIFO(先进先出)原则且队尾被连接在队首之后形成一个循环,称作“环形缓冲器”循环队列的好处是可以利用这个队列之前使用过的空间,但是他的空间大小是固定的循环队列我们使用单链表或者数组都能实现,这里先讨论使用数组的方法数组不像单链表一样可以直接做到循环,需要进行一定的操作由 head 和 tail 在之间跳动实现了数据的出入与循环,有限的空间保证先进先出重复使用tail 指向队尾数据的下一个空间。

2302_79881301的博客 1077

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

基于Java数组实现循环队列

重点:循环队列,无论使用数组实现还是链表实现,都要多开一个空间,也就意味着,要是一个存k个数据的循环队列,要开k+1个空间,否则无法实现判空和满。

qq_62274623的博客 1149

使用数组来实现循环队列

文章目录队列队列的接口循环队列的实现 使用数组来实现循环队列 队列 我们知道,在计算机科学中,程序本质上就是数据结构加上算法。数据结构是计算机存储、组织数据的方式。一般来讲,数据结构按照数据的逻辑结构分为线性结构和非线性结构两种。几乎所有的线性结构都是建立在两种最基本的结构上的:内存中连续存储的数组结构以及内存中分散存储的链表结构。 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端

weixin_44146570的博客 2465

数组实现循环队列

package com.linkedlist.exe.com.queue.exe; import com.linkedlist.exe.Demo1_LinkedList; /** * @program: ******* * @Date: ******* * @Author: Kyrie * @Description: 数组实现循环队列 * 循环队列:不但充分利用了数组的空间,还避免...

Kyrie23的博客 622

数组实现循环队列(增设队列大小size)

详解数组实现循环队列(增设队列大小size)

2301_76197086的博客 1168

数组实现队列以及循环队列

一.

weixin_50502854的博客 1795

利用数组实现一个循环队列

用数组实现循环队列的关键是头指针front和尾指针tail的解除耦合。 这里采用的方法维护一个头指针front,和一个当前容量size,尾部指针始终可以由以下公式计算出来 class MyCircularQueue { private int[] nums; private int size; private int maxSize; private in...

wwxy1995的博客 893
上一篇: 稀疏数组原理
下一篇: 链表(单链表,双链表,环形链表)
include_java0
博客等级 码龄3年 17粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值