数据结构与算法学习笔记三---循环队列的表示和实现(C++)

目录

前言

1.为什么要使用循环队列

2.队列的顺序存储方式的实现

1.定义

2.队列初始化

3.销毁

4.清空队列

5.队列是否为空

6.队列长度

7.队头

8.入队

9.出队

10.遍历队列

11.完整代码

3.参考资料


前言

    这篇文章介绍循环队列的表示和用法

1.为什么要使用循环队列

        在上一篇文章中,我们知道了顺序的循环表示和实现方法。但是我们会发现当我们在操作顺序链表的时候,我们频繁的操作顺序队列,而队列又不为空的时候,出队列的一些存储空间会变得不可用。

        如下图所示,当我rear=3,front=2的时候,顺序队列中至少有连个存储空间空间是不可以使用的,这无疑会浪费一些存储空间。那么有没有办法让我们在出队列之后,重复利用之前存储空间呢,答案是有的。

        图1.顺序队列的出队列和入队列操作示意图

        这里借鉴了网上老师的三种解决方案:

        1.使用计数器记录队列中的元素个数

        2.加标志位,删除的时候标志位置1,插入置0,当front = rear并且标志位为0,表示队列为空,当front=rear并且标志位为1的时候,表示队列经满。

        3.认为浪费一个存储空间,改成一个循环队列来实现。

        这里下面代码的表示和实现采用的第三种方案。

        关于循环队列的理解,感觉严蔚敏老师的讲解还是不错的,直接贴个图吧。

图2.严蔚敏老师数据结构与算法中关于循环队列的思路

2.队列的顺序存储方式的实现

1.定义

struct CircularQueue {int *base;int front;int rear;int maxSize; // 队列的最大容量
};

2.队列初始化

// 队列初始化
Status initQueue(CircularQueue &circularQueue, int maxSize) {circularQueue.base = new int[maxSize]; // 为循环队列分配内存if (!circularQueue.base) {return 0; // 内存分配失败}circularQueue.front = circularQueue.rear = 0; // 初始化队首和队尾指针circularQueue.maxSize = maxSize;return 1; // 初始化成功
}

3.销毁

// 销毁队列
void destroyQueue(CircularQueue &circularQueue) {if (circularQueue.base) {delete[] circularQueue.base; // 释放内存circularQueue.base = nullptr; // 将指针置为空}
}

4.清空队列

// 清空队列
void clearQueue(CircularQueue &circularQueue) {circularQueue.front = circularQueue.rear = 0; // 重置队首和队尾指针
}

5.队列是否为空

// 判断队列是否为空
bool isEmptyQueue(CircularQueue &circularQueue) {return circularQueue.front == circularQueue.rear; // 当队首和队尾指针相同时,队列为空
}

6.队列长度

// 获取队列长度
int queueLength(CircularQueue &circularQueue) {return (circularQueue.rear - circularQueue.front + circularQueue.maxSize) % circularQueue.maxSize;
}

7.队头

// 获取队首元素
Status getQueueFront(CircularQueue &circularQueue, int &frontElement) {if (isEmptyQueue(circularQueue)) {return 0; // 队列为空}frontElement = circularQueue.base[circularQueue.front];return 1; // 成功获取队首元素
}

8.入队

// 入队
bool enQueue(CircularQueue &circularQueue, int element) {// 检查队列是否已满if ((circularQueue.rear + 1) % circularQueue.maxSize == circularQueue.front) {return false; // 队列已满}// 入队操作circularQueue.base[circularQueue.rear] = element;circularQueue.rear = (circularQueue.rear + 1) % circularQueue.maxSize; // 移动队尾指针return true; // 入队成功
}

9.出队

// 出队
bool deQueue(CircularQueue &circularQueue, int &element) {// 检查队列是否为空if (isEmptyQueue(circularQueue)) {return false; // 队列为空,无法出队}// 出队操作element = circularQueue.base[circularQueue.front];circularQueue.front = (circularQueue.front + 1) % circularQueue.maxSize; // 移动队首指针return true; // 出队成功
}

10.遍历队列

// 遍历队列
void traverseQueue(CircularQueue &circularQueue) {// 遍历队列并打印元素int i = circularQueue.front;while (i != circularQueue.rear) {cout << circularQueue.base[i] << " ";i = (i + 1) % circularQueue.maxSize;}cout << endl;
}

11.完整代码

#include <iostream>
using namespace std;typedef int Status;struct CircularQueue {int *base;int front;int rear;int maxSize; // 队列的最大容量
};// 队列初始化
Status initQueue(CircularQueue &circularQueue, int maxSize) {circularQueue.base = new int[maxSize]; // 为循环队列分配内存if (!circularQueue.base) {return 0; // 内存分配失败}circularQueue.front = circularQueue.rear = 0; // 初始化队首和队尾指针circularQueue.maxSize = maxSize;return 1; // 初始化成功
}// 销毁队列
void destroyQueue(CircularQueue &circularQueue) {if (circularQueue.base) {delete[] circularQueue.base; // 释放内存circularQueue.base = nullptr; // 将指针置为空}
}// 清空队列
void clearQueue(CircularQueue &circularQueue) {circularQueue.front = circularQueue.rear = 0; // 重置队首和队尾指针
}// 判断队列是否为空
bool isEmptyQueue(CircularQueue &circularQueue) {return circularQueue.front == circularQueue.rear; // 当队首和队尾指针相同时,队列为空
}// 获取队列长度
int queueLength(CircularQueue &circularQueue) {return (circularQueue.rear - circularQueue.front + circularQueue.maxSize) % circularQueue.maxSize;
}// 获取队首元素
Status getQueueFront(CircularQueue &circularQueue, int &frontElement) {if (isEmptyQueue(circularQueue)) {return 0; // 队列为空}frontElement = circularQueue.base[circularQueue.front];return 1; // 成功获取队首元素
}// 入队
bool enQueue(CircularQueue &circularQueue, int element) {// 检查队列是否已满if ((circularQueue.rear + 1) % circularQueue.maxSize == circularQueue.front) {return false; // 队列已满}// 入队操作circularQueue.base[circularQueue.rear] = element;circularQueue.rear = (circularQueue.rear + 1) % circularQueue.maxSize; // 移动队尾指针return true; // 入队成功
}// 出队
bool deQueue(CircularQueue &circularQueue, int &element) {// 检查队列是否为空if (isEmptyQueue(circularQueue)) {return false; // 队列为空,无法出队}// 出队操作element = circularQueue.base[circularQueue.front];circularQueue.front = (circularQueue.front + 1) % circularQueue.maxSize; // 移动队首指针return true; // 出队成功
}// 遍历队列
void traverseQueue(CircularQueue &circularQueue) {// 遍历队列并打印元素int i = circularQueue.front;while (i != circularQueue.rear) {cout << circularQueue.base[i] << " ";i = (i + 1) % circularQueue.maxSize;}cout << endl;
}int main() {CircularQueue circularQueue;int maxSize = 10; // 队列的最大容量initQueue(circularQueue, maxSize); // 初始化循环队列// 测试入队for (int i = 1; i <= 5; ++i) {enQueue(circularQueue, i * 10);}// 输出队列元素cout << "队列元素:";traverseQueue(circularQueue);// 获取队首元素int frontElement;if (getQueueFront(circularQueue, frontElement)) {cout << "队首元素:" << frontElement << endl;}// 测试出队int element;for (int i = 0; i < 3; ++i) {if (deQueue(circularQueue, element)) {cout << "出队元素:" << element << endl;}}// 输出队列元素cout << "队列元素:";traverseQueue(circularQueue);// 判断队列是否为空if (isEmptyQueue(circularQueue)) {cout << "队列为空" << endl;} else {cout << "队列不为空" << endl;}// 获取队列长度cout << "队列长度:" << queueLength(circularQueue) << endl;// 清空队列clearQueue(circularQueue);// 判断清空后队列是否为空if (isEmptyQueue(circularQueue)) {cout << "清空队列后,队列为空" << endl;} else {cout << "清空队列后,队列不为空" << endl;}// 销毁队列destroyQueue(circularQueue);return 0;
}

3.参考资料

1.B站上看到的一个老师的讲解

2.数据结构C语言版(1997年清华大学出版社出版的图书)_百度百科

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

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

相关文章

深入理解Linux下的网络监控工具:iftop

目录标题 1. 什么是iftop?2. 安装iftop在Debian/Ubuntu上安装在CentOS/RHEL上安装在其他Linux发行版上 3. 使用iftop监控网络流量命令行选项界面说明交互命令 4. 相关参数及说明 在维护和监控Linux服务器时&#xff0c;了解网络流量的细节非常重要。网络监控可以帮助我们诊断延…

20240511金融读报:信贷风控卫星遥感系统实例蓝色金融

1、兴业银行信贷风控方面&#xff0c;卫星遥感应用系统&#xff08;看其他人吹了那么久&#xff0c;终于有个出来讲细节了&#xff09;&#xff1a;适用范围&#xff08;农业种植&#xff08;面积、长势、产量、市场价格、病虫害风险&#xff09;、林业&#xff08;面积、砍伐、…

远程服务器监控工具Navicat Monitor全新发布v3.0 - 支持PostgreSQL用户

Navicat Monitor 是一套安全、简单而且无代理的远程服务器监控工具。它具有强大的功能使你的监控发挥最大效用。受监控的服务器包括 MySQL、MariaDB 和 Percona Server&#xff0c;并与 Amazon RDS、Amazon Aurora、Oracle Cloud、Microsoft Azure 和阿里云等云数据库兼容。Nav…

C# 统计代码运行时长

using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;namespace Sci {/// <summary>/// 统计代码…

AlmaLinux 文件拷贝 cp命令用法示例

AlmaLinux 文件拷贝 在Linux系统中&#xff0c;文件复制可以使用cp命令。以下是一些基本的cp命令用法示例&#xff1a; 复制文件到目标目录&#xff1a; cp source.txt /destination/directory/ 复制多个文件到目标目录&#xff1a; cp file1.txt file2.txt /destination/d…

网易灵犀办公企业邮箱的IMAP和POP3服务器地址

IMAP 电子邮件地址&#xff1a;saleyouxiang.com 帐户类型&#xff1a;IMAP 接收邮件服务器&#xff1a;imaphz.qiye.163.com 发送邮件服务器&#xff1a;smtphz.qiye.163.com 用户名&#xff1a;saleyouxiang.comPOP3 电子邮件地址&#xff1a;saleyouxiang.com 帐户类型&…

进程间通信:连接不同程序世界的桥梁

目录 一、进程间通信的重要性 二、常见的进程间通信方式 三、进程间通信的目的 四、进程间通信的本质 在计算机编程的领域中&#xff0c;进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是一个至关重要的概念。当我们在操作系统中运行多个程…

YOLOv5-7.0改进(四)添加EMA注意力机制

前言 关于网络中注意力机制的改进有很多种&#xff0c;本篇内容从EMA注意力机制开始&#xff01; 往期回顾 YOLOv5-7.0改进&#xff08;一&#xff09;MobileNetv3替换主干网络 YOLOv5-7.0改进&#xff08;二&#xff09;BiFPN替换Neck网络 YOLOv5-7.0改进&#xff08;三&…

【智能算法】鹭鹰优化算法(SBOA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;Y Fu受到自然界中鹭鹰生存行为启发&#xff0c;提出了鹭鹰优化算法&#xff08;Secretary Bird Optimization Algorithm, SBOA&#xff09;。 2.算法原理 2.1算法思想…

MySQL:数据库管理的强大工具

MySQL&#xff1a;数据库管理的强大工具 文章目录 MySQL&#xff1a;数据库管理的强大工具引言MySQL的核心特性使用场景为什么选择MySQL结语 引言 在当今的数据驱动时代&#xff0c;数据库管理系统(DBMS)扮演着至关重要的角色。MySQL&#xff0c;作为一个开源的关系数据库管理…

Python - with语句 - 写一个支持with方法调用的类

Python - with语句 - 写一个支持with方法调用的类 前言 使用语句with open(a.txt, r) as f:可以自动关闭文件句柄&#xff0c;使用语句with torcu.no_grad()可以不计算梯度。 我学Py的时候咋好像没学过open和no_grad是怎么实现的&#xff1f; 于是今日了解了一下。 实现一…

【声呐仿真】学习记录2-运行ROV(带camera、sonar、dvl等传感器)例程

【声呐仿真】学习记录2-运行ROV&#xff08;带camera、sonar、dvl等传感器&#xff09;例程 前言第一阶段-学习Gazebo第二阶段-学习URDF、xacro第三阶段-寻找例程跑一个rexrov示例程序1.uuvsimulator quick_start2.能键盘控制的示例程序&#xff08;失败&#xff09;3.能键盘控…

Windows安装MySQL 8.4.0免安装版

下载地址&#xff1a;MySQL :: Begin Your Download 1 管理员权限打开cmd&#xff0c;切换到MySQL安装路径的bin目录下 cmd> C: cmd> cd ..\mysql-8.4.0-winx64\bin 2 移除已安装的MySQL服务&#xff08;若有&#xff09; 2.1 停止老的MySQL服务 net stop mysql …

Excel如何设置密码保护【图文详情】

文章目录 前言一、Excel如何设置密码保护&#xff1f;二、Excel如何取消密码保护&#xff1f;总结 前言 在软件项目开发过程中&#xff0c;会输出很多技术文档&#xff0c;其中也包括保密级别很高的服务器账号Excel文档。为了确保服务器账号相关的Excel文档的安全性&#xff0…

CSS 网格布局一行X个排列

<div class"icon-box"><divv-for"(item,index) in icon" :key"index" class"icon"style"cursor: pointer">{{item}}</div></div>.icon-box{display: grid; /**网格布局*/grid-template-columns: r…

NSS题目练习2

[LitCTF 2023]我Flag呢&#xff1f; 打开题目后查看源码即可发现flag [第五空间 2021]WebFTP 看到提示&#xff0c;首先想到用dirsearch扫描链接&#xff0c;看是否存在git泄露 发现存在git泄露&#xff0c;用githack解决 克隆提示目录为空&#xff0c;说明不正确&#xff0c…

容器监控与日志管理

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、Docker监控工具 二、容器日志工具docker logs 三、第三方日志工具 四、容器日志驱动 五、示例 5.1、查看容器中运行的进程的信息 5.2、查看…

液晶显示模块强光实验类目及太阳光模拟器

科技日新月异&#xff0c;液晶显示模块运用得也越来越广泛&#xff0c;用户在购买和使用时&#xff0c;都希望能买到显示效果好&#xff0c;性价比高的产品。本文主要介绍LCM&#xff0f;LED模块在光学方面主要测试项目类别及实验仪器。 测试项目类别 1. 透过率 透过率是指透…

【DRAM存储器二十九】DDR4介绍-DDR4 SDRAM的主要技术特性之Connectivity test mode

👉个人主页:highman110 👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容 参考资料:《镁光DDR4数据手册》 、《JESD79-4B》 目录 Connectivity test mode

Docker和containerd服务配置国内源

containerd配置国内源 在文件中添加&#xff1a; # /etc/containerd/config.toml [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"] endpoint ["registry.aliyuncs.com/google_containers"]docker配置国内源 在文件中添…