基本概念
队列与栈相似,采用先进先出的规则,就像排队买票一样
相对于栈,队列的结构可能见的更多一些。
STL中的队列
与栈一样,C++的STL库里其实也写好了队列这一结构,可以直接用
#include <iostream>
#include <queue> //STL中的队列头文件
using namespace std;
queue<int> q; //声明一个int型的队列
int main()
{
int n,t;
cin>>n;
for(int i=0;i<n;i++){
cin>>t;
q.push(t); //push函数——入队
}
while (!q.empty()){
cout<<q.front()<<" "; //front函数——取队首元素
q.pop(); //pop函数——出队
}
return 0;
}
STL中的队列有如下常用的函数:
-
q.push(n);
元素n
入队 -
q.front();
返回队首元素 -
q.back();
返回队尾元素 -
q.size();
返回队列长度 -
q.empty();
判断q
是否为空,空则为1
,则为0
-
q.pop();
队首元素出队
ps. 如果你有一个CLion:
循环队列
顾名思义,就是把队列的首尾接起来,形成一个循环的队列。队列依旧满足先进先出的规则,只是多了一个首尾相接的功能
基本结构
队列
#define maxSize 1000
struct Queue{
int data[maxSize]; //用来存数据
int front; //队首标记
int rear; //队尾标记
};
实际上,队列就是换个法子用数组,不采用原来直接调用的方法,而是用两个新的下标:
- 头“指针”
front
- 尾“指针”
rear
把这三个东西放到一起,就组成了队列的基本结构。其中数组data
用来存储数据,头“指针”front
和尾“指针”rear
则以下标的形式调用数组data
。
q.data[q.front]; //队首元素
q.data[q.rear]; //队尾元素
循环
循环主要通过maxSize
实现,maxSize
是队列的长度。
与题解——舞伴问题中的思想一样,采用对maxSize
取余的方法,实现循环。在下文“入队”部分中,会进行比较详细的描述。
初始化
void initQueue(Queue &q){
q.rear=q.front=0;
}
入队
入队的时候,用到尾指针rear
,需要将尾指针后移一位,然后存数据
q.rear++;
q.data[q.rear]=value;
如果队列是循环的,也就是首尾相接,那就会有一个衔接点,一边的下标是0
,另一边的下标是maxSize-1
。
那当q.rear++
的时候,如果rear
跨过了衔接点,如何表示?
要实现maxSize-1
直接跨到0
,可以使用取余的方法,当rear=maxSize-1
的时候,如果它再+1
,我们写:
q.rear=(q.rear+1)%maxSize;
这样的话,+1
以后的rear
变成了maxSize
,取余得0
void push(Queue &q, int value){
q.rear=(q.rear+1)%maxSize;
q.data[q.rear]=value;
}
后续代码中的取余思想与这一环节的基本一致,就不再重复说明。
出队
void pop(Queue &q){
q.front=(q.front+1)%maxSize;
}
取队首
int top(Queue q){
return q.data[(q.front+1)%maxSize];
}
判断是否为空
一般情况下,栈和队列中的empty
函数,都习惯于让empty=1
代表空,让empty=0
代表非空
bool empty(Queue q){
return q.rear==q.front; //首尾相等则队列空
}