一.队列的概念
队列是只允许在一端进行插入操作,另一端进行删除操作的线性表。
队列是一个先进先出的数据结构。 与栈(先进后出)区别
队首(front):允许删除的一端,队头。
队尾(rear): 允许插入的一端。
空队列:不含任何元素的空表。
二. 队列有关操作(以简单的顺序栈为例)
对于队列的定义
typedef struct node
{
int front,rear=-1; // 队首 与 队尾
int data[maxn]; // 队列数据
int count; // 队列长度
}Squeue;
***
Squeue S; // 定义 typedef 型的结构体;
1.队列的初始化
void init(Squeue &s)
{
s.count=0;
s.front=0; // 将队首的下标定为 0
s.rear=-1; // 队尾的下标为 -1 当插入元素时,队尾++,元素赋值到数组data中
}
2.队列判断是否为空
bool empty(Squeue s)
{
if(s.front==s.rear) return true; // if(s.count==0) return true
else return false;
// 当队首与队尾相同时 (但此时还有一种情况 队列中仅含一个元素) 所以我认为记录元素个数会更方便
}
3.入队操作
void push(Squeue &s,int x)
{
s.count++; // 元素个数+1
s.data[++s.rear]=x;// 关于 i++ 与 ++i 的用法
// 这里操作为 s.rear++ 后 再将 x 赋值到 数组 data 中,以确保队尾元素与队尾对应
}
4.出队操作
int pop(Squeue &s) // 出队操作
{
s.count--; // 元素个数 -1
return s.data[s.front++]; // 先返回 data[s.front] 元素,再进行 front++
//出队操作就是将队首下标++(右移)
}
5.返回队列队首(队尾)元素操作
int gettop(Squeue &s)
{
return s.data[s.front]; // return s.data[s.rear];
//返回队首 或 队尾元素
}
6.遍历数列操作
void printqueue(Squeue s) // 遍历队列
{
for(int i=s.front;i<=s.rear;i++) printf("%d ",s.data[i]); // 从队首到队尾
return ;
}
三.循环队列
使用原因:当插入元素过多,队列溢出,而出队后的数组的内存不再被使用,出现内存浪费的情况,采用循环队列 ,头尾相接,将内存高效利用
与顺序队列的区别:
注意数组,队首,队尾的下标不要超出 maxn ,超出部分即对其进行取模%操作
有关其操作均需要保证不超过maxn
队首进一: s.front=(s.front+1)%maxn;
队尾进一: s.rear=(s.rear+1)%maxn;
队列长度 : (s.rear-s.front+maxn)%maxn;
四.链式队列(此将与链式栈一同讲述)
五.双端队列
双端队列是允许两端都可以进行入队和出队操作的队列,分为前端和后端(与队列的区别)
大致操作:
前端进队,后端进队
前端出队,后端出队
返回前端队首元素,返回后端队尾元素
六.队列的应用
广度优先搜索(BFS)结合
例题:(待更新)