一、队列的顺序储存结构之一:循环队列
1.结构模型:
一般由一维数组和一个指向头元素位置的变量front,以及一个指向尾元素位置的变量rear组成;我们可以把这些组成部分放入一个结构体中:
struct Qnode
{
int front;
int rear;
ElementType Data[MaxSize];
};
/*C语言知识:把typedef去掉后,可以看成是声明一个struct Qnode的指针变量,而 typedef的作用就是让这个变量变成一种类型,这种类型就是这个变量的类型,这里指struct Qnode的指针类型*/
typedef struct Qnode *Queue;
2.基本形态:
可以把循环队列看成是一个首尾相连的一个环型结构,front指向第一个元素的前一个下标,rear指向尾部元素。说是环形结构,实际上就是对于一个直条形数组,人为地用(rear+1)%MaxSize把数组看成环形,初始状态:front==rear。
判断队列空、满有两种方法:
(1)空出一格:
front始终指向空出的一格;例如空出数组的第0个元素不放入数据。
当(rear+1)%MaxSize==front时,队列为满;
当front==rear时,队列为空;
(2)使用一个变量tag代表上一步是插入(tag==1)还是删除(tag==0):
当(rear+1)%MaxSize==front且上一步是插入时,队列为满
当front==rear且上一步是删除时队列为空;
3.基本算法
1.入队函数
这里用第一种方法判断是否满,入队时先让rear向后移动一格
易错:Data[]前要写PtrQ->
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;
}
2.出队函数
这里仍然用第一种方法判断是否空,出队时让front向后移动一格
ElementType DeleteQ(Queue PtrQ)
{
if(PtrQ->front==PtrQ->rear)
{
printf("队列空");
return ERROR;
}
PtrQ->front=(PtrQ->front+1)%MaxSize;
return PtrQ->Data[PtrQ->front];
}
二、队列的链式储存结构:链队列
1.结构模型:
单链表+头指针+尾指针
struct Node
{
ElementType Data;
struct Node *Next;
}
struct Qnode
{
struct Node *rear;//指向队尾节点
struct Node *front;//指向对首节点
}
typedef struct Qnode *Queue;
Queue PtrQ
2.基本形态:
rear是指向链表尾节点的,front是指向链表头节点的,因为若将单链表尾部节点删除,则找不到前面一个节点。
3.基本算法:
1.入队
同链表添加节点,注意先通过一下语句判断队列是否存在:
if(PtrQ->front==NULL)
2.出队
同链表删除节点,注意如果队列只有一个元素,那么rear指向的也是第一个元素。