【c++入门(2)】队列和queue

时间:2024-10-12 09:44:14

1.队列
队列我们先看一看线性结构:
【定义】线性结构中的数据元素之间是一对一的关系。
举个例子:
在这里插入图片描述定义:
在这里插入图片描述

【特点】
存在唯一的一个被称为“第一个”的数据元素
存在唯一的一个被称为“最后一个”的数据元素
除第一个之外,每个数据元素都只有一个前驱
除最后一个之外,每个数据元素都只有一个后继
说完了线性结构,再来看队列:
【定义】
队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出(First InFirst Out)的线性表,简称FIFO,最早进入队列的元素最早离开。允许插入的一端称为“队尾” ,允许删除的一端称为“队头”。
【小贴士】
在这里插入图片描述
队列的实现:
① 顺序表q[m]:用来存储队列中的元素,m是队列能存储元素的最大容量
② 队首指针front:指向队首元素存储的位置
③ 队尾指针rear:指向队尾元素的下一个位置(可插入元素的位置)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
长度为????的顺序队列,最多进行????次push操作后,队列就满了,即使有元素已经出队列,也无法再插入新的元素,造成空间的浪费。
在这里插入图片描述
此时,即使????中还有5个空闲位置,但是却无法再进行push操作了!
【循环队列】
循环队列是一种首尾相接的顺序存储结构,跟顺序队列使用完最后一个存储单元后就无法再存储不同,当循环队列使用完最后一个存储单元后会跳转到第一个存储单元继续存储。
在这里插入图片描述
循环队列操作
① 初始化init():front = 0,rear = 0; 此时队列为空,没有元素。
② 判断是否为空empty() :如果front== rear返回true,否则返回false。
③ 获取元素个数size():
(rear - front + m) % m
在这里插入图片描述

接下来的:
在这里插入图片描述
在这里插入图片描述
【简介】
queue是c++标准库提供的一个队列的实现,可以方便的进行入队、出队和数据访问操作。
【头文件】
queue的头文件为:queue,使用前必需过#include queue 将"queue"头文件包含进来。
【命名空间】
queue属于std名字空间,需要使用using namespace std; 引入std命名空间
在这里插入图片描述

① 在队列中顺序插入整数1, 2, 3, 4, 5, 6, 7, 8, 9 10.
② 分别输出队首和队尾元素。
③ 修改队首和队尾元素为11和20。
⑤ 将队列首元素移除。输出移除后队列中的首元素
④ 输出修改后的队列的队首和队尾
⑥ 循环输出队列中的所有元素。
注意:queue没有提供遍历所有元素的方法,不支持下标操作,也不支持迭代器。
如果需要遍历queue中所有元素,需要一遍调用front(), 一边调用pop();
操作示例:
在这里插入图片描述
来一道简单的题练练手吧:

刚学习c++的小白bob制作了一个“队列模拟系统”,并定义了以下队列的操作命令:

PRINT                输出一行:从头到尾输出队列每一个元素,元素之间用一个空格分隔

ENTER value     将value进队列

OUT                   如果队列不为空,则队首的元素出队,如果队列是空的,则不做任何动作

LENGTH           输出当前队列的元素个数

队列中的每个元素都是字符型的
输入格式

第一行,一个整数n,表示操作命令的条数

接下来n行,每行是一条命令
输出格式

对命令中的PRINT和LENGTH命令,输出相应的信息
输入输出样列
输入样例110
ENTER E
ENTER 5
ENTER t
LENGTH
ENTER 8ENTER A
PRINT
OUT
LENGTH
PRINT

输出样例13
E 5 t 8 A
4
5 t 8 A
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

queue是不支持直接遍历下标的,那么如何输出每个元素呢?
循环的输出队列的首元素,输出一个首元素,将这个首元素放到队列的末尾,然后删除首元素
输出长度:4
输出每个元素:5 t 8 A

银行排队(bank)
题目描述

K个人来银行排队办理业务,银行有n个窗口可以同时办理,每个窗口允许有m个人排队,其余的人在银行大厅等待。当某个窗口排队人数少于m时,在大厅等待的人可进入该窗口排队。每个人都有自己要办的业务,每个业务要花费一定的时间,银行的上班时间是早上8点到下午17点,若超过17点,就无法办理相关的业务了。

有q次查询,查询q个顾客办理业务结束时的时间。对于无法办理相关业务的查询,输出sorry。

假设第一位顾客从早上8点开始办理业务,k个顾客编号依次为: 12…k。 
输入格式

共3行:

第一行4个由空格分隔的正整数,分别表示n,m,k,q

第二行为k个由空格分隔的正整数,分别表示每个人办理业务所需时间

第三行为q个由空格分隔的正整数,分别表示每次查询时要查询的顾客编号
输出格式

共q行,对应每次查询的结果,每个结果的格式为: hh:mm
输入输出样列
输入样例12 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7

输出样例108:07
08:06
08:10
17:00
sorry 

说明

该银行共有两个窗口,每个窗口可同时供2人排队,总共有7人需要办理业务,有5次询问,分别是编号为34567 的顾客结束时间;输出结果显示编号为 3 的顾客在 08:07 分结束,编号为 4 的顾客在 08:06 分结束,编号为 5 的顾客在 08:10 分结束,编号为 6 的顾客在 17:00 分结束,编号为 7 的顾客在开始办理业务前,银行就下班了,所以输出 sorry。 


数据范围: 

1<=n<=10  1<=m<=5  1<=k, q<=100 

补充说明:只要顾客在下班前开始办理业务,那就要将其办理完,因此,查询输出的结束时间有可能超过 17:00
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

在这里插入图片描述
每次都队首离开队尾补人,可以为每个窗口定义一个队列记录队伍中每个人业务完成时间
queue win[11]
队首离开时 win[i].pop( )
队尾加人时 win[i].push( )
队首的人业务完成时间win[i].front( ),队尾的人业务完成时间win[i].back( )
一开始按照顺序n个队伍每个队伍先站m个人,剩余k-nm个人在大厅排队
窗口排队的人中最先办完业务的人离开,这时大厅过来一个人站在离开的人所在队伍的队尾如何判断第i个人不能办理业务了?
每个窗口中队首位置的人最先办完业务,所以所有窗口中队首位置最先办完业务的就是最先离开的。
那么大厅过来的人就排在这个人所在的窗口的末尾。
所以先把前n
m个人处理好排好队。第1个人排1号窗口,第n个人排n号窗口,第n+1个人排1号窗口…
注意k有可能是小于n*m的最终询问的是每个人业务的完成时间,所以额外定义数组,t[i]记录是第i个人的业务完成时间
窗口排队的人中哪个人最先办完业务?
如果第i个人的业务完成时间大于17点而且第i-1个人的业务完成时间大于等于17点,那么他就完成不了
这个还是有必要写一下代码的:
在这里插入图片描述queue你xue会了m?