C++循环队列 自定义queue

原理解析

看main部分的注释,对照着函数,应该能看懂。

#include <iostream>
class Queue {public:static constexpr int MAX_SIZE = 5;int items[MAX_SIZE];int front, rear;Queue() : front(-1), rear(-1) {}void enqueue(int value) {if ((rear + 1) % MAX_SIZE == front) {std::cout << "Queue is full" << std::endl;return;}if (front == -1) {front = rear = 0;} else {rear = (rear + 1) % MAX_SIZE;}items[rear] = value;}int dequeue() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return -1;}int removedItem = items[front];if (front == rear) {front = rear = -1;} else {front = (front + 1) % MAX_SIZE;}return removedItem;}void display() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return;}int i = front;while (true) {std::cout << items[i] << " ";if (i == rear) break;i = (i + 1) % MAX_SIZE;}std::cout << std::endl;}
};
int main() {Queue q;// 插入第1个值,放在索引为0的位置q.enqueue(11);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 每插入1个值,rear前进1位q.enqueue(21);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;q.enqueue(31);q.enqueue(41);q.enqueue(51);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 插入5个值后,rear为4,数组已满// 每次插入前会先检查rear的下一位是否有空位,现在rear的下一位回到了索引0,而索引0现在被front占用,所以没有空位。q.enqueue(61); // 插入失败// 每删除1个值,front前进1位q.dequeue();std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;q.dequeue();q.dequeue();q.dequeue();std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 删除4个值后,front为4// 每次删除前会先检查front是否等于rear,如果等于说明只剩最后1个值了,再次删除就是清空数组q.dequeue();// 已经是空数组 不能再删除q.dequeue(); // 删除失败std::cout << std::endl;// 插入3个后rear为2q.enqueue(12);q.enqueue(22);q.enqueue(32);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 删掉1个后front为1q.dequeue();std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;q.enqueue(42);q.enqueue(52);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 此时rear为4,rear的下一位回到索引0,此时front为1,并没有占用索引0,所以后面还能插入q.enqueue(62);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 现在rear为0,下一位是1,但1被front占用,数组满了,不能再插入q.enqueue(72); // 插入失败std::cout << std::endl;// 打印数组 从front开始到rear 每次循环索引步进1q.dequeue();q.dequeue();q.enqueue(13);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 现在front=3,rear=1,当索引步进到1时,说明打印完了,退出循环。q.display();return 0;
}

包装都头文件

实际使用要修改的地方,数组的大小,数组的类型。
还有插入函数的参数类型,删除函数的返回类型,都要改成数组中的元素类型。

// Queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
class Queue {private:static constexpr int MAX_SIZE = 5;int items[MAX_SIZE];int front, rear;public:Queue() : front(-1), rear(-1) {}void enqueue(int value) {if ((rear + 1) % MAX_SIZE == front) {std::cout << "Queue is full" << std::endl;return;}if (front == -1) {front = rear = 0;} else {rear = (rear + 1) % MAX_SIZE;}items[rear] = value;}int dequeue() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return -1;}int removedItem = items[front];if (front == rear) {front = rear = -1;} else {front = (front + 1) % MAX_SIZE;}return removedItem;}void display() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return;}int i = front;while (true) {std::cout << items[i] << " ";if (i == rear)break;i = (i + 1) % MAX_SIZE;}std::cout << std::endl;}
};
#endif

调用

// main.cpp
#include "Queue.h"
int main() {Queue q;q.enqueue(10);q.enqueue(20);q.enqueue(30);q.display();std::cout << "Dequeued: " << q.dequeue() << std::endl; // 获取删除的值 也就是先进先出std::cout << "Dequeued: " << q.dequeue() << std::endl;q.display();q.enqueue(40);q.display();std::cout << "Dequeued: " << q.dequeue() << std::endl;std::cout << "Dequeued: " << q.dequeue() << std::endl;std::cout << "Dequeued: " << q.dequeue() << std::endl; // 删除失败return 0;
}

优化

最好改成类模版,实际使用中不需要打印函数,插入函数的参数可以改成引用。删除元素的返回值因为是局部变量,无法用移动语义优化。

如果对性能要求不高,可以把数组改成std::vector,这样在构造对象时就可以指定数组大小。这里更注重性能,所以手动修改数组大小。

// Queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
#include <utility>
template <typename T> class Queue {private:static constexpr int MAX_SIZE = 1000;T items[MAX_SIZE];int front, rear;public:Queue() : front(-1), rear(-1) {}void enqueue(const T &value) {if ((rear + 1) % MAX_SIZE == front) {std::cout << "Queue is full" << std::endl;return;}if (front == -1) {front = rear = 0;} else {rear = (rear + 1) % MAX_SIZE;}items[rear] = value;}T dequeue() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return T{};}T removedItem = items[front];if (front == rear) {front = rear = -1;} else {front = (front + 1) % MAX_SIZE;}return removedItem;}
};
#endif

测试

#include "Queue.h"
#include <chrono>
#include <iostream>struct bar {float open;float height;float low;float close;
};int main() {Queue<bar> q;bar b1 = {10.0f, 15.0f, 8.0f, 12.0f};bar b2 = {20.0f, 16.0f, 9.0f, 13.0f};q.enqueue(b1);q.enqueue(b2);q.enqueue({30, 17, 10, 14}); // 直接使用初始化列表传入参数q.enqueue({40.2, 18.2, 19.2, 15.2});std::cout << q.dequeue().close << std::endl;std::cout << q.dequeue().close << std::endl;std::cout << q.dequeue().close << std::endl;std::cout << q.dequeue().close << std::endl; // 数组清空std::cout << q.dequeue().close << std::endl; // 删除失败return 0;
}

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

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

相关文章

理解 Vue.js 中的 immediate: true

理解 Vue.js 中的 immediate: true 在使用 Vue.js 时&#xff0c;监听器 (watchers) 是一种非常重要的工具&#xff0c;它允许我们观察和响应数据的变化。在定义监听器时&#xff0c;我们通常会在组件的 watch 选项中添加相关配置。immediate: true 是其中的一个配置选项。本文…

无线通讯几种常规天线类别简介

天线对于无线模块来说至关重要&#xff0c;合适的天线可以优化通信网络&#xff0c;增加其通信的范围和可靠性。天线的选型对最后的模块通信影响很大&#xff0c;不合适的天线会导致通信质量下降。针对不同的市场应用&#xff0c;天线的材质、安置方式、性能也大不一样。下面简…

近期计算机领域的热点技术

随着科技的飞速发展&#xff0c;计算机领域的新技术、新趋势层出不穷。本文将探讨近期计算机领域的几个热点技术趋势&#xff0c;并对它们进行简要的分析和展望。 一、人工智能与机器学习 人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;是近年来计算…

基于Vue 3.x与TypeScript的PPTIST本地部署与无公网IP远程演示文稿

文章目录 前言1. 本地安装PPTist2. PPTist 使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 前言 本文主要介绍如何在Windows系统环境本地部署开源在线演示文稿应用PPTist&#xff0c;并结合cpolar内网穿透工具实现随时随地远程访问与使用该项目。 PPTist …

[gpt胡说八道篇] 使用Docker快速启动Doris

Docker 是一种轻量级的虚拟化技术&#xff0c;我们可以利用 Docker 快速的在本地启动一个 Doris 的实例&#xff0c;方便进行开发和测试。下面我们来看一下如何操作。 1. 拉取 Docker 镜像 首先&#xff0c;我们需要从 Docker Hub 上拉取 Doris 的镜像。打开终端&#xff0c;输…

Qt Qvariant

QVariant 是 Qt 框架中的一个非常强大的类&#xff0c;它用于存储各种不同类型的数据&#xff0c;并提供了一种统一的方式来处理这些数据。QVariant 可以存储大多数基本数据类型&#xff0c;如整数、浮点数、字符串、日期时间等&#xff0c;以及更复杂的数据类型&#xff0c;如…

ChatGPT的原理可以通俗易懂地介绍

ChatGPT的原理可以通俗易懂地介绍如下&#xff1a; 基础架构&#xff1a; ChatGPT基于OpenAI的GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型&#xff0c;尤其是GPT-3的架构进行构建。GPT模型是一种基于Transformer架构的预训练语言模型&#xff0c;特别…

基于STM32的智能水质监测系统

目录 引言环境准备智能水质监测系统基础代码实现&#xff1a;实现智能水质监测系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;水质管理与优化问题解决方案与优化收尾与总结 1. 引言 智能水质监测系统通过使用STM32嵌…

RISC-V知识总结 —— 向量(扩展)指令集

资源1:晏明 - RISC-V向量扩展指令架构及LLVM自动向量化支持 - 202112118 - 第13届开源开发工具大会&#xff08;OSDTConf2021&#xff09;_哔哩哔哩_bilibili资源2:张先轶 - 基于RISC-V向量指令集优化基础计算软件生态【第12届开源开发工具大会&#xff08;OSDT2020&#xff09…

设计模式(实际项目)-状态机模式

需求背景&#xff1a;存在状态流转的预约单 一.数据库设计 CREATE TABLE appointment (id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 主键id,appoint_type int(11) NOT NULL COMMENT 预约类型(0:线下查房...),appoint_user_id bigint(20) NOT NULL COMMENT 预约人…

研导智能科技——AI辅助科研产品开发

人工智能&#xff08;AI&#xff09;技术的飞速发展为科研领域带来了革命性的变化。本公司致力于开发基于人工智能的科研辅助产品&#xff0c;旨在通过智能化手段提高科研人员的工作效率和研究质量。目前&#xff0c;我们成功开发了研导学术平台&#xff08;www.zhiyanxueshu.c…

Linux运维:MySQL数据库(1)

1.信息与数据&#xff1a; 数据是信息的载体&#xff0c;信息是数据的内涵。数据库就是存储数据的仓库&#xff0c;并长期存储在计算机磁盘中&#xff0c;可由多个用户和应用程序共享的数据集合&#xff0c;就是数据库。 2.数据库中的数据的特点&#xff1a; 2.1.数据是按照某…

RuleApp1.4.6文章社区客户端 广告联盟支持Docx导入

支持编译为安卓&#xff0c;苹果&#xff0c;小程序&#xff0c;H5网页的社区客户端代码&#xff0c;包括文章模块&#xff0c;用户模块&#xff0c;动态模块&#xff0c;支付模块&#xff0c;聊天模块&#xff0c;广告模块&#xff0c;商城模块等基础功能&#xff0c;包含VIP会…

C++的模板(九):模板的实例化问题

前文子系统中的例子&#xff0c; SubSystem内部用了STL库的map模板: template <class Event, class Response> class SubSystem{ public:map<Event*, Response*> table; public:void bind(Event *e, Response *r);void unbind(Event *e); public:int OnMessage(E…

10位时间戳、13位时间戳、17位时间戳,以及在JavaScript中的格式转换

一、介绍 1、10位时间戳 2、13位时间戳 3、17位时间戳 4、时间戳转换工具 二、13位时间戳的转换 1、转标准日期 2、转格式化日期 三、10位时间戳的转换 1、转标准日期 2、转格式化日期 四、17位时间戳的转换 1、解析思路 2、解析过程 &#xff08;1&#xff09;统…

C++系统编程篇——Linux第一个小程序--进度条

&#xff08;1&#xff09;先引入一个概念&#xff1a;行缓冲区 \r和\n \r表示回车 \n表示回车并换行 ①代码一 #include<stdio.h> #include<unistd.h> int main()…

django学习入门系列之第三点《伪类简单了解》

文章目录 hover&#xff08;伪类&#xff09;after&#xff08;伪类&#xff09;往期回顾 hover&#xff08;伪类&#xff09; 伪类指的是用冒号加的 hover样式指的是&#xff0c;当用户光标移动到设定区域后&#xff0c;所执行的用法 如&#xff1a; <!DOCTYPE html>…

【C语言】函数无参数有返回值、有参数无返回值、有参数有返回值

文章目录 前言C语言函数的分类和使用无参数有返回值的函数有参数无返回值的函数有参数有返回值的函数 总结 前言 在C语言中&#xff0c;函数是一种重要的组织代码的方式。根据函数的参数和返回值&#xff0c;我们可以将函数分为三类&#xff1a;无参数有返回值、有参数无返回值…

清理未使用的镜像和容器

删除未使用的镜像和容器&#xff1a; docker system prune -a清理构建缓存&#xff1a; Docker 会缓存构建过程中使用的中间镜像&#xff0c;可以通过以下命令清理它们&#xff1a; docker builder prune定期清理旧镜像&#xff1a; 定期运行以下命令清理旧镜像&#xff1a; …

通过代理从ARDUINO IDE直接下载开发板包

使用免费代理 实现ARDUINO IDE2.3.2 下载ESP8266/ESP32包 免费代理 列表 测试代理是否可用的 网站 有时&#xff0c;代理是可用的&#xff0c;但依然有可能找不到开发板管理器的资料包。 可以多换几个代理试试。 代理的配置 文件 -> 首选项 -> 网络 进入后做如下配置…