队列 Queue
线性表:线性表是具有相同数据类型的n个数据元素的有限序列,其中n为表长。当n=0时,线性表是一个空表
栈:是只允许在一端进行插入和删除的线性表
队列:是只允许在一端进行插入,在另一端进行删除的线性表(入队,出队)
terms:
- 队头:允许删除元素的一端
- 队尾:允许插入元素的一端
- 空队列
特点:先进入队列的先出队
常见的基本操作
InitQueue(&Q):初始化队列,创建一个空队列Q。
DestoryQueue(&Q):销毁队列。销毁并释放队列Q所占用的内存空间。
EnQueue:入队。若队列Q没满,将x加入,使之成为新的队尾。
DeQueue:出队。若队列Q非空,删除队头元素,并用x返回。
GetHead(Q,&x):读队头元素,若队列Q非空,则将队头元素赋值给x。
QueueEmpty(Q):判断队空,若队列为空返回true,否则返回false。
用顺序存储的方式实现队列
#define MaxSize 10
typedef struct{
ElemType data[MaxSize]; //用静态数组存放队列元素
int front,rear; //队头指针和队尾指针
}SqQueue;
void testQueue() {
SqQueue Q; //声明一个队列,顺序存储
//后续操作
}
队头指针:指向队头元素
队尾指针:指向队尾元素的下一个位置(下一个应该插入的位置)
初始化
//初始化队列
void InitQueue(SqQueue &Q){
Q.rear=Q.front=0;
}
//判断队列是否为空
bool QueueEmpty(SqQueue Q){
if(Q.rear==Q.front) //队空条件
return true;
else
return false;
}
入队操作(从队尾方向)
//入队操作
bool EnQueue(SqQueue &Q,ElemType x){
if(队列已满) **//见下**
return false; //队满则报错
Q.data[Q.rear]=x; //将x插入队尾
Q.rear=Q.rear+1; //将队尾指针后移
return true;
}
当rear队尾指针等于maxsize时,并不能确定队列已经存满,因为从front队头指针出队时,队尾指针的下标是不变的
所以Q.rear=(Q.rear+1)%MaxSize; //将队尾指针后移
- 模运算可以将无限的整数域映射到有限的整数集合
- 用模运算将储存空间逻辑上变为了环状
- 用这种方式形成的队列叫做循环队列
- 队列已满的条件是队尾指针的下一个元素是队头指针
(Q.rear+1)%MaxSize==Q.front
- 代价要牺牲掉一个存储单元,防止已满和为空的判断条件相同
出队操作
//出队操作
bool DeQueue(SeQueue &Q,ElemType