循环队列、双端队列 C和C++
队列
目录
概念
实现方式
顺序队列
循环队列
队列的数组实现
用循环链表实现队列
STL 之 queue 实现队列
STL 之 dequeue 实现双端队列
概念
队列是一种特殊的线性表,它只允许在表的前端(称为队头,front)进行删除操作——出队,而在表的后端(称为队尾,rear)进行插入操作——入队,是一种操作受限的线性表。
最先进入队列的元素最先被删除,是“先进先出”的线性表。
实现方式
- 数组
- 链表
- C++ 中可以使用 STL 中的 queue 实现
- 其中 STL 中还包括双端队列 dequeue
顺序队列
必须静态分配或者动态申请空间,并设置两个指针管理,一个是队头指针 front(指向队头元素),另一个是队尾指针 rear(指向下一个入队元素的存储位置)。
队空的判断条件是:front==rear,队满的条件为:rear==MAXQSIZE。
循环队列
为了使队列空间可以重复使用,可以对循环队列进行改进,无论是插入或者删除,一旦 rear 指针或者 front 指针超出了所分配的队列空间,就让它指向这篇连续空间的起始位置,自己从 MAXQSIZE 增 1 变为 1,可以用取余运算实现: (rear+1)%MAXQSIZE、 (front+1)%MAXQSIZE.
其中队空的判断条件为:front==rear,队满的条件为:(rear+1)%MAXQSIZE==front。
队列的数组实现
定义一个结构体实现队列:
struct node {int* data;int front;int rear;
};
初始化队列:(将队头和队尾指针都赋为 1),数组长度为 MAXQSIZE,开辟一块空间为 MAXQSIZE-1 的数组:
//为队列开辟空间并初始化(也可以在结构体中定义int data[MAXQSIZE])
void InitQueue(struct node& Q) {Q.rear = 1;Q.front = 1;Q.data = (int*)malloc(MAXQSIZE+1 * sizeof(int));
}
入队:
//入队
int EnQueue(struct node &Q,int y) {if (Q.rear != MAXQSIZE) {Q.data[Q.rear] = y;Q.rear++;return 1;}return 0;
}
出队:
//出队
int DeQueue(struct node& Q, int &y) {if (Q.rear != Q.front){y = Q.data[Q.front];Q.front++;return 1;}return 0;
}
总代码为:
//数组实现队列
#include<stdio.h>
#include<stdlib.h>
#define MAXQSIZE 100
int queue[MAXQSIZE];
struct node {int* data;int front;int rear;
};
//为队列开辟空间并初始化(也可以在结构体中定义int data[MAXQSIZE])
void InitQueue(struct node& Q) {Q.rear = 1;Q.front = 1;Q.data = (int*)malloc(MAXQSIZE+1 * sizeof(int));
}
//入队
int EnQueue(struct node &Q,int y) {if (Q.rear != MAXQSIZE) {Q.data[Q.rear] = y;Q.rear++;return 1;}return 0;
}
//出队
int DeQueue(struct node& Q, int &y) {if (Q.rear != Q.front){y = Q.data[Q.front];Q.front++;return 1;}return 0;
}
int main() {int n;int x, y;struct node Q;InitQueue(Q);//以1开头为插入(插入操作输入两个数),以0开头为删除printf("输入操作个数:(以1开头为插入(插入操作输入两个数),以0开头为删除)\n");scanf("%d", &n);while (n--) {printf("输入操作:");scanf("%d", &x);if (x == 1){scanf("%d", &y);if (EnQueue(Q, y))printf("入队成功\n");elseprintf("入队失败\n");}else if (x == 0){if (DeQueue(Q, y) == 0)printf("出队失败\n");elseprintf("出队的元素为:%d\n",y);}else{printf("输入正确的操作\n");n++;}}return 0;
}
用循环链表实现队列
不用循环时将初始化时的 Q->next=Q 删去。
以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,不设头指针。
定义一个结构体:
struct node {int data;struct node* next;
};
入队:
//入队
void EnQueue(struct node* Q, int y) {struct node* p;p = (struct node*)malloc(sizeof(struct node));p->data = y;p->next = Q->next;Q->next = p;Q = p;
}
出队:
//出队
int DeQueue(struct node* Q, int& y) {if (Q->next == Q)return 0;struct node* p;p = Q->next;y = p->data;Q->next = p->next;free(p);return 1;
}
总代码:
//以带头结点的循环链表表示队列,
//并且只设一个指针指向队尾结点,不设头指针。
#include<stdio.h>
#include<stdlib.h>
struct node {int data;struct node* next;
};
//循环队列的初始化
void InitQueue(struct node* Q) {Q->next = Q;//初始化循环队列
}
//入队
void EnQueue(struct node* Q, int y) {struct node* p;p = (struct node*)malloc(sizeof(struct node));p->data = y;p->next = Q->next;Q->next = p;Q = p;
}
//出队
int DeQueue(struct node* Q, int& y) {if (Q->next == Q)return 0;struct node* p;p = Q->next;y = p->data;Q->next = p->next;free(p);return 1;
}
int main() {struct node* Q;Q = (struct node*)malloc(sizeof(struct node));InitQueue(Q);printf("输入操作个数:(以1开头为插入(插入操作输入两个数),以0开头为删除)\n");int x, y, n;scanf("%d", &n);while(n--){printf("输入操作:");scanf("%d", &x);if(x==1){scanf("%d", &y);EnQueue(Q, y);printf("入队成功\n");}else if(x==0){if (DeQueue(Q, y) == 1)printf("%d\n", y);elseprintf("出队失败\n");}}return 0;
}
STL 之 queue 实现队列
要加上头文件:#include<queue>
对应的函数:
构造空队列:
queue<int>q;
总代码:
//用queue函数实现队列
#include<iostream>
#include<queue>
using namespace std;
int main() {queue<int>q;int n;int x, y;printf("输入操作个数:");scanf("%d", &n);printf("以1开头为插入(插入操作输入两个数),以0开头为删除\n");while (n--) {scanf("%d", &x);if (x == 1) {scanf("%d", &y);q.push(y);}else if(x==0){if (!q.empty()) {//判断队列不为空printf("%d\n", q.front());q.pop();}elseprintf("出队失败\n");}else{printf("输入正确的操作\n");n++;}printf("队列中元素个数为:%d\n", q.size());}return 0;
}
STL 之 dequeue 实现双端队列

//用dequeue实现双端队列
#include<iostream>
#include<deque>
using namespace std;
struct node {int *data;
}Q;
int main() {deque<int>q(10);deque<int>::iterator idex;for (int i = 0; i < 10; i++) {q[i] = i;}for (int i = 0; i < 10; i++) {printf("%d ", q[i]);}printf("\n");//在头尾加入新元素printf("加入新元素后:\n");q.push_back(100);//加入队尾q.push_front(10);//加入队头printf("输出deque的数据:\n");for (idex = q.begin(); idex != q.end(); idex++) {printf("%d ", *idex);}printf("\n");//查找int x = 5;idex = find(q.begin(), q.end(), x);if (idex != q.end())printf("找到%d元素\n",x);elseprintf("队列中没有%d元素\n",x);//在头尾删除数据q.pop_back();//删除队尾q.pop_front();//删除队头printf("输出deque的数据:\n");for (idex = q.begin(); idex != q.end(); idex++) {printf("%d ", *idex);}return 0;
}
相关文章:
循环队列、双端队列 C和C++
队列 目录 概念 实现方式 顺序队列 循环队列 队列的数组实现 用循环链表实现队列 STL 之 queue 实现队列 STL 之 dequeue 实现双端队列 概念 队列是一种特殊的线性表,它只允许在表的前端(称为队头,front)进行删除操作…...
正则表达式(语法+例子)
文章目录一、介绍二、语法1、匹配字符2、表示数量的字符3、边界字符4、其他字符5、转义字符三、例子1、邮箱2、用逗号分隔的数字集合1,23、允许一位小数4、20yy-mm-dd日期格式5、手机号6、匹配html、xml标签一、介绍 正则表达式(Regular Expression)&am…...
Properties和IO流集合的方法
方法名说明void load(InputStream inStream)从输入字节流读取属性列表(键和元素)void load(Reader reader)从输入字符流读取属性列表(键和元素对)void store(OutputStream out,String comments)将此属性列表(键和元素对…...
python 生成器、迭代器、动态新增属性及方法
目录 一、生成器 1、生成器定义 2、生成器存在的意义 3、创建生成器方式一(生成器表达式) 4. 创建生成器方式二(生成器函数) 1. 生成器函数 2. 生成器函数的工作原理 5. 总结 1. 什么是生成器 2. 生成器特点 二、迭代器…...
Java处理JSON
Java处理json有很多种方法,在这里总结一下。 1 Jackson Spring MVC 默认采用Jackson解析Json,出于最小依赖的考虑,也许Json解析第一选择就应该是Jackson。 1.1 引入的包 Jackson核心模块由三部分组成:jackson-core、jackson-a…...
58-Map和Set练习-LeetCode692前k个高频单词
题目 给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。 示例 1: 输入: words ["i", "love", …...
线程生命周期及五种状态
文章目录一、线程生命周期及五种状态1、New(初始化状态)2、Runnable(就绪状态)3、Running(运行状态)4、Blocked(阻塞状态)5、Terminated(终止状态)二、线程基本方法1、线程等待(wait)2、线程睡眠(sleep)3、…...
OBCP第八章 OB运维、监控与异常处理-灾难恢复
灾难恢复是指当数据库中的数据在被有意或无意破坏后复原数据库所需要执行的活动 回收站:回收站在原理上说就是一个数据字典表,放置用户删除的数据库对象信息。用户删除的东西被放入回收站后,其实仍然占据着物理空间,除非您手动进…...
亚马逊云科技Serverless Data:数字经济下的创新动能
Serverless时代已经到来!企业的技术架构,总是伴随着不断增长的数据与日趋复杂的业务持续演进。如何通过构建更易用的技术架构来聚焦在业务本身,而不必在底层基础设施的管理上投入过多的精力,是数据驱动型企业需要思考的重要议题。…...
【Ruby学习笔记】15.Ruby 异常
Ruby 异常 异常和执行总是被联系在一起。如果您打开一个不存在的文件,且没有恰当地处理这种情况,那么您的程序则被认为是低质量的。 如果异常发生,则程序停止。异常用于处理各种类型的错误,这些错误可能在程序执行期间发生&…...
聊聊MySQL主从延迟
文章目录 MySQL 的高可用是如何实现的呢?二、什么是主备延迟?三、主备延迟常见原因1、备库机器配置差2、备库干私活3、大事务四、主库不可用,主备切换有哪些策略?1、可靠优先2、可用优先实验一实验二3、结论MySQL 的高可用是如何实现的呢? 高可用性(high availability,缩…...
【C++从0到1】19、C++中多条件的if语句
C从0到1全系列教程 1、多条件的if语句 语法: if (表达式一) { // 表达式一为真时执行的语句。 } else if (表达式二) {// 表达式二为真时执行的语句。 } else if (表达式三) {// 表达式三为真时执行的语句。 } …… else if (表达式n) {// 表达式n为真时执行的语句。…...
【多微电网】计及碳排放的基于交替方向乘子法(ADMM)的多微网电能交互分布式运行策略研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Linux(centos7)安装防火墙firewalld及开放端口相关命令
安装firewalld 防火墙命令: yum install firewalld 安装完成,查看防火墙状态为 not running,即未运行,输入命令开启: 添加开放端口: 防火墙相关命令: 查看防火墙状态 systemctl status firewa…...
Linux部署.Net Core Web项目
本文主要记录我在Linux(Ubuntu)上部署.net core 的操作记录,也便于以后部署。 如对您有所帮助,不胜荣幸~ 文章目录前言一、准备工作1. 版本信息2. windows端web项目二、操作步骤1. Linux 配置 .net 运行环境1.1 查看最新 .net 运行环境的下载路径1.2 安装…...
【C++】STL之stack、queue的使用和模拟实现+优先级队列(附仿函数)+容器适配器详解
之前的一段时间,我们共同学习了STL中一些容器,如string、vector和list等等。本章我们将步入新阶段的学习——容器适配器。本章将详解stack、queue的使用和模拟实现优先级队列(附仿函数)容器适配器等。 目录 (一&…...
第⑦讲:Ceph集群RGW对象存储核心概念及部署使用
文章目录1.RadosGW对象存储核心概念1.1.什么是RadosGW对象存储1.2.RGW对象存储架构1.3.RGW对象存储的特点1.4.对象存储中Bucket的特性1.4.不同接口类型的对象存储访问对比2.在集群中部署RadosGW对象存储组件2.1.部署RGW组件2.2.集群中部署完RGW组件后观察集群的信息状态2.3.修改…...
从异步到promise
一,背景 1.1,js的单线程 这一切,要从js诞生之初说起,因为js是单线程的语言。 js单线程原因:作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程&…...
Linux系统中进行JDK环境的部署
一、为什么需要部署JDK。 JDK:Java Development Kit,是用于Java语言开发的环境。 部署JDK不需要懂得Java语言,只需要掌握Linux相关命令即可。 二、部署版本与环境。 系统:安装在VMware环境下的CentOS7.6; JDK版本&a…...
Leetcode.1033 移动石子直到连续
题目链接 Leetcode.1033 移动石子直到连续 Rating : 1421 题目描述 三枚石子放置在数轴上,位置分别为 a,b,c。 每一回合,你可以从两端之一拿起一枚石子(位置最大或最小),并将其放入…...
vLLM-v0.17.1行业落地:法律科技公司合同关键条款抽取与风险提示服务
vLLM-v0.17.1行业落地:法律科技公司合同关键条款抽取与风险提示服务 1. vLLM框架简介 vLLM是一个专为大型语言模型(LLM)设计的高性能推理和服务库,最初由加州大学伯克利分校的天空计算实验室开发,现已发展成为社区驱动的开源项目。这个框架…...
s2-pro音色复用效果实测:不同参考音频时长(3s/10s/30s)对合成质量影响
s2-pro音色复用效果实测:不同参考音频时长(3s/10s/30s)对合成质量影响 1. 引言 s2-pro作为Fish Audio开源的专业级语音合成模型镜像,其音色复用功能在实际应用中表现如何?本文将针对一个关键问题展开实测:…...
保姆级教程:用snntorch在MNIST上训练你的第一个脉冲神经网络(附完整代码)
从零开始:用snntorch构建你的第一个脉冲神经网络手记 第一次接触脉冲神经网络(SNN)时,我被它模拟生物神经元放电的特性深深吸引。与传统人工神经网络不同,SNN通过离散的脉冲信号传递信息,更接近人脑的工作机…...
openGauss服务化部署实战:systemd单元文件配置详解
1. 为什么需要systemd管理openGauss 每次重启服务器都要手动启动数据库?这种操作既低效又容易出错。把openGauss交给systemd管理后,你会发现数据库服务像系统内置服务一样听话——开机自动启动、异常自动重启、日志集中收集,这才是专业运维该…...
告别定位漂移:用Python手把手实现GNSS载波相位平滑伪距(附代码)
告别定位漂移:用Python手把手实现GNSS载波相位平滑伪距(附代码) 在无人机自主飞行或自动驾驶小车导航时,你是否遇到过这样的困扰:明明设备静止不动,地图上的定位点却像喝醉酒一样左右摇摆?这种&…...
阿里云盘Refresh Token获取终极指南:3分钟搞定扫码授权全流程
阿里云盘Refresh Token获取终极指南:3分钟搞定扫码授权全流程 【免费下载链接】aliyundriver-refresh-token QR Code扫码获取阿里云盘refresh token For Web 项目地址: https://gitcode.com/gh_mirrors/al/aliyundriver-refresh-token 阿里云盘refresh token…...
路径规划算法技术选型与实战指南:从理论到工程落地
路径规划算法技术选型与实战指南:从理论到工程落地 【免费下载链接】PathPlanning Common used path planning algorithms with animations. 项目地址: https://gitcode.com/gh_mirrors/pa/PathPlanning 当仓库机器人在密集货架间灵活避障,当无人…...
PasteMD真实案例分享:从零散笔记到结构化学习计划的全过程
PasteMD真实案例分享:从零散笔记到结构化学习计划的全过程 1. 引言:当杂乱笔记遇上智能格式化 你是否经历过这样的困境?电脑桌面上散落着十几个临时创建的记事本文件,手机备忘录里堆满了未经整理的零散想法,会议录音…...
解决Redis测试环境搭建难题的try.redis工具:零配置交互式终端功能全解析
解决Redis测试环境搭建难题的try.redis工具:零配置交互式终端功能全解析 【免费下载链接】try.redis A demonstration of the Redis database. 项目地址: https://gitcode.com/gh_mirrors/tr/try.redis 在日常开发中,开发者常常面临Redis测试环境…...
Golang错误处理实战:defer、panic和recover的正确打开方式(附避坑指南)
Golang错误处理实战:defer、panic和recover的正确打开方式(附避坑指南) 在Golang的世界里,错误处理是一门艺术。与传统的try-catch机制不同,Go采用了独特的defer-panic-recover组合拳。这种设计哲学体现了Go语言"…...
