#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20
typedef int ElemType;
typedef struct SqQueue
{
ElemType data[MAXSIZE];
int front;
int rear;
}SqQueue;
SqQueue* Create_Queue()
{
SqQueue *queue = (SqQueue *)malloc(sizeof(SqQueue));
if(queue == NULL)
{
return NULL;
}
queue->front = 0;
queue->rear = 0;
return queue;
}
//循环队列
// rear front
//a6 a3 a4 a5
// 0 1 2 3 4
//此时就看做满
//就像排队一样,尾进头出
int EnQueue(SqQueue *queue,ElemType data)
{
if(queue == NULL)
{
return -1;
}
if((queue->rear+1)%MAXSIZE == queue->front)
{
//队满
return -2;
}
queue->data[queue->rear] = data;
queue->rear = (queue->rear + 1) % MAXSIZE;
return 0;
}
int DeQueue(SqQueue *queue,ElemType *value)
{
if(queue == NULL || value == NULL)
{
return -1;
}
if(queue->front == queue->rear)
{
//没有数据
return -2;
}
*value = queue->data[queue->front];
queue->front = (queue->front + 1) % MAXSIZE;
return 0;
}
int Queue_Length(SqQueue *queue)
{
if(queue == NULL)
{
return -1;
}
return (queue->rear - queue->front + MAXSIZE) % MAXSIZE;
}
void Destroy_Queue(SqQueue *queue)
{
if(queue == NULL)
{
return;
}
free(queue);
}
int main()
{
SqQueue *queue = NULL;
int i,value;
queue = Create_Queue();
if(queue == NULL)
{
return -1;
}
for(i=0;i<=20;i++)
{
if(EnQueue(queue,i) != 0)
{
printf("enqueue %d error\n",i);
}
else
{
printf("enqueue %d ",i);
}
}
DeQueue(queue,&value);
printf("Dequeue %d\n",value);
printf("Queue length = %d",Queue_Length(queue));
Destroy_Queue(queue);
return 0;
}
结果:
enqueue 0 enqueue 1 enqueue 2 enqueue 3 enqueue 4 enqueue 5 enqueue 6 enqueue 7
enqueue 8 enqueue 9 enqueue 10 enqueue 11 enqueue 12 enqueue 13 enqueue 14 enque
ue 15 enqueue 16 enqueue 17 enqueue 18 enqueue 19 error
enqueue 20 error
Dequeue 0
Queue length = 18
可以看到19与20插入是失败的,虽然我们这的MAXSIZE是20,但实际上只能存储19个,少的那一个作为判断队列是否已满而被保留。这里的队列的顺序存储是队尾进,队头出。其实也可以像线性表一样,只是头出的时候,要移动整个数组。所以这里采取循环队列的形式。队尾的指针不只局限于对头之后,也可以在前面。就像文中注释的这段:
// rear front
//a6 a3 a4 a5
// 0 1 2 3 4
一看,大家就明白了。
总的来说,还是那句老话,队列只是特殊的线性表,完全可以用我之前写的线性表来代替实现,只是插入的位置与出去的位置被局限了而已。大家可以试试。