队列
在日常生活中,我们免不了排队,食堂打饭、排队买奶茶、排队等公交,第1个结束操作才轮到第2个、、、第n个,有时候是否很厌恶一些人的插队?本次我们来学习跟线性表和栈不同的,文明的”队列“。
队列与我们前面说的栈类似,是一种只允许在一端进行插入,另一端进行删除的线性表。
在学习的时候我们可以两者对比着学习栈的传送门
- 队头(front):允许删除的一端
- 队尾(rear):允许插入的一端
- 空队列:不含任何元素的空表
队列的特点:先进先出
队列的两种存储表示方式:
- 顺序队列
- 链式队列
顺序队列的定义
#ifndef QUEUE_H
#define QUEUE_H
typedef struct
{
int data[maxSize];
int front;//队首指针
int rear;//队尾指针
}SqQueue;//顺序队类型定义
#endif
一天,yyyloki特别想喝奶茶,于是她来到了奶茶店,发现前面有5个人在排队等着点单,加上yyyloki就有6个人。==她们都在等待“入队”==当她们都点好了最热门的饮品后各自拿着自己的订单,此时服务员叫号了,“1号的奶茶好了”,1号拿着她的奶茶,美滋滋的走了(1号出队),此时排队的就还剩2、3、4、5和yyyloki了。
循环队列
在循环队列中,通常让队尾指针rear指向刚进队元素的位置。让队首指针front指向刚出队的元素的位置。
- 进队:rear向后移动
- 出队:front向后移动
假溢出:当队中无元素,但仍然无法让元素进队。
为了解决假溢出的问题,产生了循环队列。
循环队列的要素:
- 队空状态:qu.rear==qu.front。
- 队满状态:(qu.rear+1)%maxSize==qu.front
- 进队操作:
qu.rear=(qu.rear+1)%maxSize;
qu.data[qu.rear]=x;
- 出队操作:
qu.front=(qu.front+1)%maxSize;
x=qu.data[qu.front];
通过代码的实现我们来看看,顺序队列的特性:
init.h
#ifndef _INIT_H
#define _INIT_H
#define TRUE 1
#define FASLE 0
#define OK 1
#define ERROR -1
#define OVERFLOW -2
typedef int Status;
#endif
Queue.h
#ifndef QUEUE_H
#define QUEUE_H
#define maxSize 100
typedef struct
{
int data[maxSize];
int front;//队首指针
int rear;//队尾指针
}SqQueue;//顺序队类型定义
Status displayQueue(SqQueue &qu);
void initQueue(SqQueue &qu);
Status EnQueue(SqQueue &qu,int x);
Status DeQueue(SqQueue &qu,int &x);
#endif
Queue.cpp
#include "init.h"
#include "queue.h"
#include <iostream>
using namespace std;
void initQueue(SqQueue &qu)
{
qu.front=qu.rear=0;//队首指针与队尾指针重合,并且指向0
}
Status EnQueue(SqQueue &qu,int x)
{
if ((qu.rear+1)%maxSize==qu.front) return 0;//判断队满,队满不能入队
qu.rear=(qu.rear+1)%maxSize;//若队未满,移动指针
qu.data[qu.rear]=x;//插入元素
return 1;
}
Status DeQueue(SqQueue &qu,int &x)
{
if (qu.rear==qu.front) return 0;//判断队空
qu.front=(qu.front+1)%maxSize;
x=qu.data[qu.front];
return 1;
}
Status displayQueue(SqQueue &qu)
{
int i,j;
i=qu.rear;
j=qu.front;
cout<<"打印队列:";
while(i!=j)
{
j=(j+1)%maxSize;
cout<<qu.data[j]<<" ";
}
cout<<endl;
return 0;
}
demo.cpp
#include "init.h"
#include "queue.h"
#include <iostream>
using namespace std;
int main()
{
int x;
SqQueue sq;
initQueue(sq);
EnQueue(sq,1);
EnQueue(sq,2);
EnQueue(sq,3);
EnQueue(sq,4);
EnQueue(sq,5);
EnQueue(sq,6);
displayQueue(sq);//此时队中的元素为 1 2 3 4 5 6
if(DeQueue(sq,x)==1) cout<<x<<endl;//1 出队
displayQueue(sq);//此时队中的元素为 2 3 4 5 6
EnQueue(sq,7);
EnQueue(sq,8);
EnQueue(sq,9);
EnQueue(sq,10);
if(DeQueue(sq,x)==1) cout<<x<<endl;
EnQueue(sq,11);
EnQueue(sq,12);
EnQueue(sq,13);
EnQueue(sq,14);
displayQueue(sq);
system("pause");
getchar();
return 0;
}
运行结果:
考研真题:
已知循环队列存储在一维数组A[0,…,n-1]中,且队列非空时front和rear分别指向队头和队尾元素,若初始时队列为空,且要求第1个进入队列的元素存储在A[0]处,则初始时front和rear的值分别是( B )。
A.0,0
B.0,n-1
C.n-1,0
D.n-1,n-1