2.3.1队列及顺序存储实现
什么是队列?
队列Queue:具有一定操作约束的线性表。
只能在一端插入,在另一端删除。
数据插入:入队列AddQ
数据删除:出队列DeleteQ
先来先服务,先进先出
队列的抽象数据类型
队列的顺序存储实现
队列的顺序存储实现,通常由一个一维数组,一个记录队列头元素位置的变量front,和一个记录队列尾元素位置的变量rear组成。
实现
#define MAXSIZE 1000
struct QNode{
ElementType Data[MAXSIZE];
int rear;//实际上是数组的下标
int front;
};
typedef struct QNode* Queue;
顺环队列的理解
当进行过插入及删除操作后,有时会出现队列还有位置却无法插入的问题。这时候我们引入顺环队列的定义。
可以理解为一个圆圈,如图。
队列为空的情况:front==rear
队列为满的情况:front==rear
解决方案:
使用额外标记:size或tag域
用来记录元素个数,根据0或n判断
插入时tag=1,删除时为0,根据最后一次tag的值来判断
仅使用n-1个数组空间
操作
入队列----采用解决方案:仅使用n-1个数组空间
满的情况:rear+1==front
在程序上需要实现5的下一个是0,我们采用求余的方法
(5+1)%6==0
一点理解:理不清拿笔写一下就懂了。
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];
}
}
2.3.2队列的链式存储实现
基本思路:
链表头做删除和插入操作都很方便,链表尾做插入没问题,但做删除的话找不到前一个位置。
实现
struct Node{
ElementType Data;
struct Node* Next;
};
struct QNode{//链队列结构
struct Node* rear;//指向队尾节点
struct Node* front;//指向队头节点
};
typedef struct QNode* Queue;
Queue PtrQ;
操作
1.不带头结点的链式队列出队操作示例
ElementType Delete(Queue PtrQ)
{
struct Node* Frontcell;
ElementType FrontElem;
if(PtrQ->front==NULL)//队列为空
{
printf("队列空");
return ERROR;
}
Frontcell=PtrQ->front;//指向要删除的节点
if(PtrQ->front==PtrQ->rear)//队列只有一个元素
{
PtrQ->front=PtrQ->rear=NULL;
}else{
PtrQ->front=Frontcell->Next;
}
FrontElem=Frontcell->Data;
free(Frontcell);
return FrontElem;
}