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

目录

0  循环队列

1  特定条件下循环队列队/空队满判断条件

1.1 队列为空的条件

1.2 队列为满的条件

2  循环队列的实现

3  示例

4  注意事项


0  循环队列

        循环队列(Circular Queue)是队列的一种实现方式,它通过将队列存储空间的最后一个位置与第一个位置相连接,形成一个循环的队列结构,从而可以更加高效地利用存储空间。在循环队列中,当队尾指针到达队列存储空间的末尾时,下一个插入操作将从头开始,即实现了队列的“循环”。

1  特定条件下循环队列队/空队满判断条件

        在循环队列中,判断队列是否为空或已满是一个重要的操作。由于循环队列的特性,我们不能简单地通过比较队头指针(front)和队尾指针(rear)是否相等来判断队列是否为空或已满,因为当队列为空时和当队列满时,这两个指针都可能相等。

1.1 队列为空的条件

        队列为空的条件相对简单,即队头指针和队尾指针相等:

front == rear

1.2 队列为满的条件

        队列为满的条件需要特殊处理,因为当队列满时,队尾指针的下一个位置应该是队头指针。但是,我们不能直接比较 rear + 1 和 front 是否相等,因为 rear + 1 可能会超出数组索引的范围。因此,我们需要使用模运算 % 来确保索引在数组范围内循环。

        有两种常见的实现方式:

        ①浪费一个空间
        在这种方法中,我们故意让队列中始终保持一个空闲位置,这样当 rear 的下一个位置是 front 时,队列就是满的。

(Q.rear + 1) % MAX_SIZE == Q.front

        这种方法的好处是实现简单,缺点是浪费了一个空间。

        ②使用额外的变量
        我们可以使用一个额外的变量(例如 size 或 count)来跟踪队列中元素的数量。当 size 等于 MAX_SIZE 时,队列就是满的。

size == MAX_SIZE

        这种方法需要额外的空间来存储元素数量,但是空间利用率更高,没有浪费。

        下面循环队列的实现将采用第一种方法。

2  循环队列的实现

        循环队列通常使用一个固定大小的数组来实现,同时需要两个指针来指示队头和队尾的位置。为了区分队列是满还是空,我们可以使用以下几种方法之一:

  1. 设置一个标记变量:当队列为空时,该变量为某个特定值(如 false);当队列满时,该变量为另一个特定值(如 true)。
  2. 使用队尾指针的下一个位置:当队尾指针的下一个位置等于队头指针时,队列满;当队头指针等于队尾指针时,队列空(但需要注意区分队列空和队列满时队头队尾指针重合的情况)。

        循环队列实现:

#include <stdio.h>  
#include <stdlib.h>  
#include <stdbool.h>  
  
#define MAX_SIZE 100  
  
typedef struct {  
    int data[MAX_SIZE];  
    int front; // 队头指针  
    int rear;  // 队尾指针  
} CircularQueue;  
  
// 初始化循环队列  
void initQueue(CircularQueue *Q) {  
    Q.front = Q.rear = 0;  
}  
  
// 判断队列是否为空  
bool isEmpty(CircularQueue *Q) {  
    if(Q.front==Q.rear)
        return true;
    else
        return false;
} 
  
// 判断队列是否已满  
bool isFull(CircularQueue *Q) {  
    if((Q.rear + 1) % MAX_SIZE == Q.front)
        return false;
}  
  
// 入队操作  
bool enqueue(CircularQueue *Q, int x) {  
    if (isFull(Q)) {  
        printf("Queue is full\n");  
        return false;  
    }  
    Q.data[Q.rear] = x;  
    Q.rear = (Q.rear + 1) % MAX_SIZE;  
    return true;  
}  
  
// 出队操作  
bool dequeue(CircularQueue *Q, int &x) {  
    if (isEmpty(Q)) {  
        printf("Queue is empty\n");  
        return false;  
    }  
    x = Q.data[Q.front];  
    Q.front = (Q.front + 1) % MAX_SIZE;  
    return true;  
}  
  
int main() {  
    CircularQueue Q;  
    initQueue(&Q);  
      
    // 入队操作  
    enqueue(&Q, 1);  
    enqueue(&Q, 2);  
    enqueue(&Q, 3);  
      
    // 出队操作  
    int x;  
    dequeue(&Q, &x);  
    printf("Dequeued: %d\n", x); // 输出 1  
      
    // ... 其他操作 ...  
      
    return 0;  
}

3  详解队空/队满的判定

        例如:一个队列的入队顺序为 a,b,c,d,e :

        ①空队;

        ②a,b,c入队;

        ③不舍弃条件下;

        ④牺牲一个单元条件下。

        综上,在牺牲一个单元下,可以正确的判定该队列是队空还是队满。

4  注意事项

  • 当队尾指针 rear 到达数组的末尾时,需要将其回绕到数组的开头,这通常通过取模运算 % MAX_SIZE 来实现。
  • 类似地,当队头指针 front 向前移动并到达数组的开头时,也需要将其回绕到数组的末尾(尽管在出队操作中不直接需要,但在某些情况下,如查找队中某个元素时可能会用到)。
  • 在判断队列是否已满时,注意区分队列满和队列空时队头队尾指针重合的情况。在循环队列中,当队尾指针的下一个位置等于队头指针时,队列满。因此,我们使用 (Q.rear + 1) % MAX_SIZE == Q.front 来判断队列是否已满。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java】Hutool发送邮件功能

目录 开通qq邮箱的stmp实战pom.xmlapplication.ymlcontrollerservice实体类辅助类 需要实现一个通过邮箱找回密码的功能 正常来说&#xff0c;找回密码的验证码&#xff0c;一般来说&#xff0c;都是通过手机号来找回的居多&#xff0c;那为什么会有通过邮箱找回的方式该说不说…

Luminar Neo - AI智能修图软件超越PS和LR,简单易用又高效!

很多人都想美化自己的风景和人物的图片&#xff0c;得到更加美丽耀眼的效果。然而&#xff0c;专业摄影师和设计师在电脑上使用的后期工具如 Photoshop 和 LightRoom 过于复杂。 通常为了一些简单的效果&#xff0c;你必须学习许多教程。而一些针对小白用户的“一键式美颜/美化…

Python第二语言(八、Python包)

目录 1. 什么是Python包 2. 创包步骤 2.1 new包 2.2 查看创建的包 2.3 拖动文件到包下 3. 导入包 4. 安装第三方包 4.1 什么是第三方包 4.2 安装第三方包-pip 4.3 pip网络优化 1. 什么是Python包 包下有__init__.py就是包&#xff0c;无__init__.py就是文件夹。于Ja…

开发没有尽头,尽力既是完美

最近遇到了一些难题&#xff0c;开发系统总有一些地方没有考虑周全&#xff0c;偏偏用户使用的时候“完美复现”了这个隐藏的Bug...... 讲道理创业一年之久为了生存&#xff0c;我一直都有在做复盘&#xff0c;复盘的核心就是&#xff1a;如何提升营收、把控开发质量&#xff0…

gdb调试器

目录 一、前言 debug和release 二、调试操作 2.1、退出 quit 2.2、调试 run 2.3、打断点 b 2.4、查看断点 info b 2.5、查看代码 l 2.6、删除断点 d 2.7、逐过程 n 2.8、打印变量内容 p 2.9、逐语句&#xff08;进入函数&#xff09; s 2.10、查看函数调用堆栈 …

先进封装技术的一些优缺点探讨

半导体封装技术是半导体制造过程中的关键环节&#xff0c;它不仅保护了芯片免受物理损伤&#xff0c;还提供了电气连接和散热功能。随着技术的发展&#xff0c;出现了多种先进的封装技术&#xff0c;每种技术都有其特定的应用场景和优缺点。 --> 1. 传统封装技术 【优点】&…

微服务之基本介绍

一、微服务架构介绍 1、微服务架构演变过程 单体应用架构->垂直应用架构一>分布式架构一>SOA架构-->微服务架构 ① 单体应用架构 互联网早期&#xff0c; 一般的网站应用流量较小&#xff0c;只需一个应用&#xff0c;将所有功能代码都部署在一起就可以&#x…

嵌入式仪器模块:波形发生器模块(嵌入式)

• 16 位分辨率 • 125 MHz 刷新率 • 支持生成 FSK/ASK 信号 应用场景 • 生成任意标准波形或用户自定义波形 • 在特殊协议通信中模拟某个波形 • 无线充电&#xff08;信号调制&#xff09; 道114输出阻抗Low-ZLow-ZLow-Z输出范围 5 V 5 V 6 V耦合DCDCDC带宽4 MHz10 M…

【小沐学Python】Python实现Web服务器(CentOS下打包Flask)

文章目录 1、简介2、下载Python3、编译Python4、安装PyInstaller5、打包PyInstaller6、相关问题6.1 ImportError: urllib3 v2 only supports OpenSSL 1.1.1, currently the ssl module is compiled with OpenSSL 1.0.2k-fips 26 Jan 2017. See: https://github.com/urllib3/url…

AXI Quad SPI IP核中的STARTUPEn原语参数

启动STARTUPEn Primitive &#xff08;原语&#xff09;参数在 FPGA的主 SPI模式下非常有用。当你启用这个参数时&#xff0c;对于 7 系列设备&#xff0c;STARTUPE2 原语会被包含在设计中&#xff1b;而对于 UltraScale™ 设备&#xff0c;则是 STARTUPE3 原语。这些原语在 FP…

基于NodeJs 的Vue安装和创建项目

基于NodeJs 的Vue安装和创建项目 一、Node.js的下载与安装 下载地址&#xff1a; https://nodejs.org/en/download/prebuilt-installer 安装完之后&#xff0c;启动 cmd命令行&#xff0c;验证 Node.js 是否安装成功 二、配置npm的全局模块的存放路径以及缓存的路径 注&…

大模型应用工程化过程

近年来&#xff0c;以人工智能为代表的新一代信息技术加速应用&#xff0c;特 别是基于大模型、大数据、大算力的 ChatGPT 的发布&#xff0c;标志着人 工智能技术取得里程碑式突破&#xff0c;推动科技创新进入新阶段。随着 大模型技术的迅猛发展和场景价值的不断涌现&#xf…

HTML-CSS练习例子

HTML CSS 练习 https://icodethis.com 作为前端练习生。不敲代码只看&#xff0c;入门是很慢的&#xff0c;所以直接实战是学习前端最快的途径之一。 这个网站练习HTML CSS的&#xff0c;可以打开了解一下&#xff0c;可以每天打卡&#xff0c;例子简单&#xff0c;循序渐进&…

每日5题Day19 - LeetCode 91 - 95

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;91. 解码方法 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int numDecodings(String s) {int n s.length();//注意我们dp的范围是n1int[] d…

AtCoder Beginner Contest 356 G. Freestyle(凸包+二分)

题目 思路来源 quality代码 题解 对n个泳姿点(ai,bi)建凸包&#xff0c;实际上是一个上凸壳&#xff0c; 对于询问(ci,di)来说&#xff0c;抽象画一下这个图&#xff0c;箭头方向表示询问向量 按x轴排增序&#xff0c;并且使得后面的y不小于前面的y&#xff0c;因为总可以多…

ThreadCache线程缓存

一.ThreadCache整体结构 1.基本结构 定长内存池利用一个自由链表管理释放回来的固定大小的内存obj。 ThreadCache需要支持申请和释放不同大小的内存块&#xff0c;因此需要多个自由链表来管理释放回来的内存块.即ThreadCache实际上一个哈希桶结构&#xff0c;每个桶中存放的都…

LLM的基础模型8:深入注意力机制

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

SpringBoot之静态资源

默认静态资源路径 classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/ 静态资源路径下的文件&#xff0c;可以通过根目录访问 resources 文件夹的文件如下图所示&#xff1a; 启动项目&#xff0c;分别访问以下路径&#xff1a; ht…

STM32 proteus + STM32Cubemx仿真教程(第一课LED教程)

文章目录 前言一、STM32点亮LED灯的原理1.1GPIO是什么1.2点亮LED灯的原理 二、STM32Cubemx创建工程三、proteus仿真电路图四、程序代码编写1.LED灯操作函数介绍HAL_GPIO_WritePin函数原型参数说明示例代码 HAL_GPIO_TogglePin函数原型参数说明示例代码 2.代码编写3.烧写程序 总…