队列是一种功能受限的线性表,在队列的一端进行入队,另一端出队,可以理解为一端插入数据,一端删除数据。所以队列是先进先出,区别于栈。队列常用的是循环队列,但是在循环队列中,还存在一个问题就是如何判断队满和队空的问题,这里我们分别介绍两种解决此问题的方法。
先给int起别名 #define TYPE int
一、额外多申请一个内存空间
这种方法的代价是浪费一个单位的内存空间,在队空时front==rear,队满时(rear+1)%cap == front
这里先确定队列的结构:连续空间的首地址,队列容量,队头下标,队尾下标
创建
//创建
ArrayQueue *create_queue(int cap)
{
ArrayQueue *queue=malloc(sizeof(ArrayQueue));
queue->ptr=malloc(sizeof(TYPE)*(cap+1));
queue->cap=cap+1;
queue->front=0;
queue->rear=0;
return queue;
}
销毁
//销毁
bool destroy_queue(ArrayQueue *queue)
{
if(!queue) return false;
free(queue->ptr);
queue->ptr=NULL;
free(queue);
queue=NULL;
return true;
}
入队
//入队
bool in_queue(ArrayQueue *queue,TYPE val)
{
if((queue->rear+1)%queue->cap==queue->front) return false;
queue->ptr[queue->rear]=val;
queue->rear=(queue->rear+1)%queue->cap;
return true;
}
出队
//出队
bool out_queue(ArrayQueue *queue)
{
if(queue->rear==queue->front) return false;
queue->front=(queue->front+1)%queue->cap;
return true;
}
取队头
//取队头
bool head_queue(ArrayQueue *queue,TYPE *val)
{
if(queue->rear==queue->front) return false;
*val=queue->ptr[queue->front];
return true;
}
取队尾
//取队尾
bool tail_queue(ArrayQueue *queue,TYPE *val)
{
if(queue->rear==queue->front) return false;
*val=queue->ptr[(queue->rear-1+queue->cap)%queue->cap];
return true;
}
数量
//数量
int cnt_queue(ArrayQueue *queue)
{
return (queue->rear-queue->front+queue->cap)%queue->cap;
}
遍历
//遍历
void show_queue(ArrayQueue *queue)
{
int temp=queue->front;
for(int i=0;i<cnt_queue(queue);i++)
{
printf("%d ",queue->ptr[temp++]);
}
printf("\n");
}
二、增加数据项
当我们在设计队列的结构时,可以增加一项用来记录队列中的元素数量,这样一来,当数据项为0时队空,当数据项等于队列容量时队满。
typedef struct ArrayQueue
{
TYPE *ptr;
int cap;
int cnt;
int front;
int rear;
}ArrayQueue;
创建
//创建
ArrayQueue *create_queue(int cap)
{
ArrayQueue *queue=malloc(sizeof(ArrayQueue));
queue->ptr=malloc(sizeof(TYPE)*cap);
queue->cnt=0;
queue->cap=cap;
queue->front=0;
queue->rear=-1;
return queue;
}
销毁
//销毁
bool destroy_queue(ArrayQueue *queue)
{
if(0==queue->cnt) return false;
free(queue->ptr);
queue->ptr=NULL;
free(queue);
queue=NULL;
return true;
}
入队
//入队
bool in_queue(ArrayQueue *queue,TYPE val)
{
if((queue->cnt==queue->cap)) return false;
queue->rear=(queue->rear+1)%queue->cap;
queue->ptr[queue->rear]=val;
queue->cnt++;
return true;
}
出队
//出队
bool out_queue(ArrayQueue *queue)
{
if(0==queue->cnt) return false;
queue->front=(queue->front+1)%queue->cap;
queue->cnt--;
return true;
}
取队头
//取队头
bool head_queue(ArrayQueue *queue,TYPE *val)
{
if(0==queue->cnt) return false;
*val=queue->ptr[queue->front];
return true;
}
取队尾
//取队尾
bool tail_queue(ArrayQueue *queue,TYPE *val)
{
if(0==queue->cnt) return false;
*val=queue->ptr[queue->rear];
return true;
}
遍历
//遍历
void show_queue(ArrayQueue *queue)
{
int i = queue->front;
for (int j = 0; j < queue->cnt; j++)
{
printf("%d ", queue->ptr[i]);
i = (i + 1) % queue->cap;
}
printf("\n");
}
OK完活,到这里我们通过两种方式解决了队满队空的判断问题,在主函数的测试不再过多赘述。
over