一.基础知识
1.什么是队列?
满足先进先出的一种存储结构。
2.队列的分类?
1.链式队列(用链表实现的)
2.静态队列(用数组实现的)
3.为什么静态队列必须是循环队列?
如图:
如果不是循环队列,那么“队首”以下的元素都会被浪费掉!
4.循环队列需要几个参数来确定?
需要两个参数:front(队首)、rear(队尾)
1.队列初始化的时候:rear=front=0
2.队列空的时候:front==rear
3.队列不空的时候: rear 指向队列第1个元素、front指向队列最后一个元素的下一个元素(目的是为了好判断队列是否为空 )
二、队列的实现(用数组实现循环队列)
1.初始化一个队列
1.1定义队列的数据结构
//定义队列的数据结构
typedef struct Queue
{
int * pBase;
int front;
int rear;
}QUEUE,*PQUEUE;
1.2初始化一个队列
front与rear的值都为0。
//初始化一个队列
void initQueue(PQUEUE pQ,int length)
{
pQ->pBase=(int *)malloc(sizeof(int)*length);
if(pQ->pBase==NULL)
{
printf("队列初始化失败\n");
exit(-1);
}
else
{
pQ->front=0;
pQ->rear=0;
}
}
2.入队
2.1判断队列是否已满
我们可以让最后一个rear不存数据
如上图:可以作为一个满队列。判断是否已满就很好说了:
(rear+1)%length==front时,证明已满
//判断队列是否已满
int isFull(PQUEUE pQ,int length)
{
//这里是循环队列,所以是(pQ->rear+1)%length,不是(pQ->rear+1)
if((pQ->rear+1)%length==pQ->front)
{
return 1;
}
else
{
return 0;
}
}
2.2入队
分为3步:
1.判断队列是否已满,不满的话则允许入队
2.在rear处入队
3.rear++
//入队
void enQueue(PQUEUE pQ,int length,int val)
{
if(isFull(pQ,length))
{
printf("队列已满,不可入队!\n");
}
else
{
pQ->pBase[pQ->rear]=val;
pQ->rear++;
}
}
3.遍历队列
3.1判断队列是否为空
如图:当front与rear相等时,证明这是一个空队列
(为此,rear指向最后1个元素的下1个元素,好判断是否为空)
//判断队列是否为空
int isEmpty(PQUEUE pQ)
{
if(pQ->front==pQ->rear)
{
return 1;
}
else
{
return 0;
}
}
3.2遍历队列
//遍历队列
void traverseQueue(PQUEUE pQ)
{
if(isEmpty(pQ))
{
printf("空队列\n");
}
else
{
int i=pQ->front;
while(i!=pQ->rear)
{
printf("%d ",pQ->pBase[i]);
i++;
}
}
}
4.出队
//出队
void deQueue(PQUEUE pQ,int length)
{
if(isEmpty(pQ))
{
printf("队列为空,不可出队\n");
}
else
{
//循环队列,所以是(pQ->front+1)%length
pQ->front=(pQ->front+1)%length;
}
}
三、总体代码
#include <stdio.h>
#include <stdlib.h>
//定义队列的数据结构
typedef struct Queue
{
int * pBase;
int front;
int rear;
}QUEUE,*PQUEUE;
//初始化一个队列
void initQueue(PQUEUE pQ,int length)
{
pQ->pBase=(int *)malloc(sizeof(int)*length);
if(pQ->pBase==NULL)
{
printf("队列初始化失败\n");
exit(-1);
}
else
{
pQ->front=0;
pQ->rear=0;
}
}
//判断队列是否已满
int isFull(PQUEUE pQ,int length)
{
if((pQ->rear+1)%length==pQ->front)
{
return 1;
}
else
{
return 0;
}
}
//入队
void enQueue(PQUEUE pQ,int length,int val)
{
if(isFull(pQ,length))
{
printf("队列已满,不可入队!\n");
}
else
{
pQ->pBase[pQ->rear]=val;
pQ->rear++;
}
}
//判断队列是否为空
int isEmpty(PQUEUE pQ)
{
if(pQ->front==pQ->rear)
{
return 1;
}
else
{
return 0;
}
}
//遍历队列
void traverseQueue(PQUEUE pQ)
{
if(isEmpty(pQ))
{
printf("空队列\n");
}
else
{
int i=pQ->front;
while(i!=pQ->rear)
{
printf("%d ",pQ->pBase[i]);
i++;
}
}
}
//出队
void deQueue(PQUEUE pQ,int length)
{
if(isEmpty(pQ))
{
printf("队列为空,不可出队\n");
}
else
{
pQ->front=(pQ->front+1)%length;
}
}
int main()
{
QUEUE q;
initQueue(&q,6);
enQueue(&q,6,3);
enQueue(&q,6,2);
enQueue(&q,6,1);
enQueue(&q,6,4);
enQueue(&q,6,5);
deQueue(&q,6);
deQueue(&q,6);
deQueue(&q,6);
traverseQueue(&q);
return 0;
}