一.循环队列
1.循环队列的结构
循环队列即为头尾相接的队列,它的最大存储空间和顺序队列一样由数组界定,但队列的长度并不一定等同于数组的长度;循环队列的队首和队尾分别由两个指针front、rear标识,于是这样就能做到首尾相接。
循环列表的结构图示:
代码示例:
#define MAXSIZE 100
typedef struct
{
ElemType data[MAXSIZE];
int front;
int rear;
}Queue;
/*初始化队列*/
Status InitQueue(Queue *Q)
{
Q->front=0;
Q->rear=0;
return 1;
}
2.队列长度
要注意在循环队列中front可能在rear之前也可能出现在rear之后,所以不能单纯的的用front - rear计算队列长度。这里给出计算公式:
length=(rear - front + MAXSIZE)%MAXSIZE
(MAXSIZE为队列的最大长度,即数组的长度)
3.空队列与满队列的判断
空队列:front==rear
队列已满:(rear+1)%MAXSIZE==front
(为了与空队列的判断区分,当数组仅剩一个空闲单元时,即rear后移一位等于front时认为队列已满)
4.入队
①判断队列是否已满,若满则返回
②队列未满,插入数据到队尾
③rear后移
代码示例:
Status EnQueue(Queue *Q,ElemType e)
{
if((Q->rear+1)%MAXSIZE==Q->front)//判断队满(即rear后移一位等于front)
return 0;
Q->data[Q->rear]=e;
Q->rear=(Q->rear+1)%MAXSIZE;//rear后移一位
return 1;
}
5.出队
①判断队列是否为空,若空则返回
②队列不为空,删除队首
③front后移
代码示例:
ElemType DeQueue(Queue *Q)
{
ElemType e;
if(Q->front==Q->rear)//判断队空
return 0;
e=Q->data[Q->front];//队首赋给e
Q->data[Q->front]=0;//删除队首
Q->front=(Q->front+1)%MAXSIZE;//front后移一位
return e;
}
循环队列完整代码下载地址:https://download.csdn.net/download/luotuoxiansheng/10762208
二.链队列
1.链式队列结构
链队列即队列的链式存储结构,结构上就是一个单链表,但数据只能是头进尾出。链式结构更加的灵活,特别是在存储空间上,基本不会出现溢出的情况,所以不用像循环队列一样判断队列是否已满,且空间的利用率相对较高。
链队列front指向头结点,头结点不存储数据,rear指向队尾结点。
代码示例:
typedef int ElemType;
typedef int Status;
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
typedef struct
{
Node *front;
Node *rear;
int count;
}LinkQueue;
/*初始化队列*/
Status InitQueue(LinkQueue *Q)
{
//队列头结点的队头和队尾指针申请内存
Q->front = Q->rear = (Node *)malloc(sizeof(Node));
if(!Q->front) //检测是否申请失败
{
printf(" malloc error!\n");
return 0;
}
//设置头结点指针域为空
Q->front->next=NULL;
Q->count=0;
return 1;
}
2.入队
①数据结点插入队尾
②rear指针后移
代码示例:
Status EnQueue(LinkQueue *Q,ElemType e)
{
Node *newnode=(Node *)malloc(sizeof(Node));
if(!newnode)//内存分配失败
return 0;
newnode->data=e;
newnode->next=NULL;
Q->rear->next=newnode;//e插入队尾
Q->rear=newnode;//队尾变为newnode
Q->count++;
return 1;
}
3.出队
代码示例:
ElemType DeQueue(LinkQueue *Q)
{
Node *p;
ElemType e;
if(Q->front==Q->rear)//判断队空
return 0;
p=Q->front->next;//将要出队的结点暂存给p
e=p->data;//结点数据保存给e
Q->front->next=p->next;//在队列中删除结点p
if(Q->rear==p)//若队头是队尾,删除后将rear指向front
Q->rear=Q->front;
free(p);
Q->count--;
return e;
}
链队列完整代码下载地址:https://download.csdn.net/download/luotuoxiansheng/10762213
以上是对循环队列、链队列的学习与分享