队列及实现
什么是队列?
- 队列(Queue):具有一定操作约束的线性表
- 操作和删除操作:只能在一端插入,而在另一端删除。
队列的操作
- 数据插入:入队列(AddQ)
- 数据删除:出队列(DeleteQ)
- 先来先服务:FIFO
队列的存储实现
队列的顺序储存结构通常由一个一维数组和一个记录队列头元素位置的front和一个记录队列尾元素位置的变量rear组成。
#define MaxSize <存储数据元素的最大个数>
struct QNode
{
ElementType Data[MaxSize];
int rear;
int front; // front指向Data数组第一个元素的前一个位置
};
typedef struct QNode* Queue;
顺环队列
思考:
- 这种方案:堆栈空和满的判别条件分别是什么?
- 为什么会出现空、满无法判断?根本原因?
Ans:
- 队列装载元素个数情况有7种:0(空队列),1(一个元素),2,3,4,5,6
- front与rear“差距”有6种情况:0,1,2,3,4,5
- 差距有n种,个数有n+1种,注定无法表示全
解决方案:
- 使用额外标记:Size(存储队列元素个数),Tag(记录最后一次操作是删除还是插入,0为删除,1为插入)
- 仅使用n-1个数组空间
// 入队列
void AddQ(Queue PtrQ,ElementType item)
{
if ((PtrQ->rear+1)%MaxSize==PtrQ->front)
{
printf("队列满");
return;
}
PtrQ->rear=(PtrQ->rear+1)%MaxSize;
PtrQ->Data[PtrQ->rear]=item;
}
// 出队列
ElementType DeleteQ(Queue PtrQ)
{
if (PtrQ->rear==PtrQ->front)
{
printf("队列空");
return ERROR;
}
else
{
PtrQ->front=(PtrQ->front+1)%MaxSize;
return PtrQ->Data[PtrQ->front];
}
}