静态队列,可以理解为一个功能受限的数组
静态队列只能是循环队列,如果不是循环的,那必然在不断出队的操作中,队列的内存空间变得越来越小。
下面是代码。
我们队列的结构体里面包含了四个元素,队列的头和队列的尾,以及一个指向调用数组的第一个元素位置的指针,还有这个数组本身的长度。
在循环队列中,判断是否为空的条件是rear == front,为了避免判断是否为满的条件与之冲突,我们设计时就留出一个位置不用来存储数据。当(rear + 1)%length == front的时候就直接报满。
我们是如何实现循环的?
在队列的头和尾移动时,我们不能简单地rear += 1;而是应该rear = (rear+1) % length,那么每次在数组的最后一个位置时都可以顺利地循环到数组的第一个位置来。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct Queue
{
int *pBase;//此指针指向数组的第一个元素的地址
int front;//队列的头
int rear;//队列的尾
int length;//数组的长度
}QUEUE;
void init_(QUEUE*);//初始化操作
void show(QUEUE*);//遍历操作
void append(QUEUE*,int);//入队操作
void remove_(QUEUE*);//出队操作
int len(QUEUE*);//返回一个现有队列的有效长度
int isempty(QUEUE*);//判断是否为空
int isfull(QUEUE*);//判断是否为满
int main(void)
{
QUEUE q;
init_(&q);
show(&q);
append(&q,1);
append(&q,2);
append(&q,3);
show(&q);
remove_(&q);
show(&q);
}
init_(QUEUE* pq)
{
int len;
printf("请输入创建队列的长度:\n");
scanf("%d",&len);//这里的len是你想存放的最大数目,实际的数组长度还比len大1
pq->length = len + 1;//length代表数组的全长,len代表存放的最大容量
pq->pBase = (int*)malloc(sizeof(int)*(len+1));
pq->front = 0;
pq->rear = 0;
}
void show(QUEUE* pq)
{
int i = pq->front;
while( i != pq->rear)
{
printf("%d ",pq->pBase[i]);
i = (i+1)% pq->length;
}
printf("\n");
}
int len(QUEUE* pq)
{
int i = pq->rear - pq->front;
if( i > 0 )
{
return i;
}
else
{
return pq->length + i;
}
}
int isempty(QUEUE* pq)
{
if( pq->front == pq->rear )
{
return 1;
}
else
{
return 0;
}
}
int isfull(QUEUE* pq)
{
if ((pq->rear+1)% pq->length == pq->front )
{
return 1;
}
else
{
return 0;
}
}
void append(QUEUE* pq,int val)
{
if( isfull(pq) )
{
printf("队列已满,无法添加!\n");
exit(-1);
}
else
{
pq->pBase[pq->rear] = val;
pq->rear = (pq->rear+1)%pq->length;
}
}
void remove_(QUEUE* pq)
{
if (isempty(pq))
{
printf("队列为空,无法出队!\n");
exit(-1);
}
else
{
pq->front = (pq->front+1) % pq->length;
}
}