队列(queue)是一种只允许在一端插入元素,而在另一端删除元素的线性表。它是一种先进先出(First In First Out,FIFO)的线性表。我们把允许插入的一端称为队尾,允许删除元素的一端称为队头。由于队列也是一种线性表,所以队列的实现也有顺序存储和链式存储这两种实现。当队列顺序存储时,入队列操作所需要的时间复杂度为O(1),而出队列的时间复杂度为O(n)。因为删除队头元素时,需要将后面的元素整体向前移动。为了避免顺序存储队列删除元素时,导致其他元素的移动,可以考虑循环队列。循环队列是指队列的首尾两个指针可以绕着队列循环移动。例如,当往循环队列中添加元素(入队列)时,将队列的尾指针rear向后移动一步,如果其超出了队列的最大长度MAXSIZE则回绕到队列的头部继续;当从循环队列中取元素(出队列)时,将队列的头指针front向后移动一步,如果其超出了队列的最大长度MAXSIZE则回绕到队列的头部继续。我们指定当队列的头指针front和尾指针rear重合时,即front == rear时,队列为空。当rear与front相差一个位置时,我们就认定队列已满,即(rear+1)%MAXSIZE == front。对于队列的长度计算,则是通过公式:length = (rear -front+MAXSIZE)%MAXSIZE。 循环队列涉及的主要操作有:初始化队列、判断一个队列是否为空、返回队列的长度、入队列操作以及出队列操作等。其代码实现如下:
#define MAXSIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
//循环队列的顺序存储结构
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];//循环队列大小
int front;//队列头指针
int rear;//队列尾指针
}SqQueue;
/* *
* 初始化一个队列
* 让头尾指针相同,从队头开始
* */
Status InitQueue(SqQueue *Q){
Q->rear = 0;
Q->front = 0;
}
/* *
* 求循环队列的长度
* 返回队列的长度
* */
int QueueLength(SqQueue Q){
return ((Q.rear-Q.front + MAXSIZE)%MAXSIZE);
}
/* *
* 循环队列的入队操作
* 成功返回1,
* 失败返回0
* */
Status EnQueue(SqQueue *Q,ElemType e){
if((Q->rear + 1)%MAXSIZE == Q->front)
return ERROR;//循环队列已满
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1)%MAXSIZE;//队尾指针指向下一个元素
return OK;
}
/* *
* 循环队列的出队列操作
* 成功返回1,并把元素通过e返回
* 失败返回0
* */
Status DeQueue(SqQueue *Q,ElemType *e){
if(Q->front == Q->rear)
return ERROR;//循环队列为空
*e = Q->data[Q->front];
Q->front = (Q->front + 1)%MAXSIZE;//队头指针指向下一个元素
return OK;
}
/* *
* 判断一个循环队列是否为空
* 如果队列为空,则返回TRUE,反之则返回FALSE
* */
Status QueueEmpty(SqQueue Q){
return Q.rear == Q.front?TRUE:FALSE;
}
测试代码为:
int main(){
SqQueue Q;
InitQueue(&Q);
printf("The queue length is:%d\n",QueueLength(Q));
if(QueueEmpty(Q))
printf("The Queue is empty!\n");
int i;
for(i = 0; i < 10; i++){
int e = rand()%100 + 1;
EnQueue(&Q,e);
printf("The queue Length is:%d\n",QueueLength(Q));
}
int m;
while(!QueueEmpty(Q)){
if(DeQueue(&Q,&m))
printf("delete the queue element is :%d\n",m);
printf("The queue length is:%d\n",QueueLength(Q));
}
return 0;
}