为了解决假溢出的办法就是当队尾"满"了,就再从头开始,也就是头尾相接的循环。我们把队列的这种头尾相接的顺序存储结构称为循环队列。链式存储是不会出现这个问题的。
当队列为空时,此时front==rear,但是现在队列满的条件也是front==rear,怎么判断队列究竟是空还是满呢?
1.解决办法一是设置一个标志变量flag,当front==rear,且flag=0时为空队列,当front==rear,且flag=1时为队列满
2.解决办法二是当队列为空时,条件还是front==rear,但是当队列满时,少用一个元素空间,约定为"队列头指针在队列尾指针的下一位置上"作为堆满条件,变成程序就是(rear+1)%MAXN==front
基本上看的程序都是解决办法2,不知道为什么很少用解决办法一,解决办法一也不难,实现的代码还是照着书上的敲,感觉基本不需要修改,另外自己实现了getTop和getRear函数,分别是获取对头和队尾的元素,代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAXQSIZE 6
struct SqQueue{
int *base;
int front;
int rear;
};
int InitQueue(SqQueue *queue){
queue->base=(int *)malloc(MAXQSIZE*sizeof(int));
if(!queue->base) return 0;
queue->front=queue->rear=0;
return 1;
}
int QueueLength(SqQueue *queue){
return (queue->rear-queue->front+MAXQSIZE)%MAXQSIZE;
}
int EnQueue(SqQueue *queue,int e){
if((queue->rear+1)%MAXQSIZE==queue->front) return 0; //对满条件
queue->base[queue->rear]=e;
queue->rear=(queue->rear+1)%MAXQSIZE;
return 1;
}
int DeQueue(SqQueue *queue,int *e){
if(queue->rear==queue->front) return 0; //对空条件
*e=queue->base[queue->front];
queue->front=(queue->front+1)%MAXQSIZE;
return 1;
}
int GetTop(SqQueue *queue){
if(queue->rear==queue->front) return 0;
return queue->base[queue->front];
}
int GetRear(SqQueue *queue){
if(queue->rear==queue->front) return 0;
return queue->base[queue->rear-1];
}
int main(){
SqQueue queue;
InitQueue(&queue);
int i;
for(i=0;i<3;i++) EnQueue(&queue,i+1);
printf("对长:%d\n",QueueLength(&queue));
int val=-1;
DeQueue(&queue,&val);
printf("出对元素:%d\n",val);
DeQueue(&queue,&val);
printf("出对元素:%d\n",val);
printf("对长:%d\n",QueueLength(&queue));
for(i=3;i<6;i++) EnQueue(&queue,i+1);
DeQueue(&queue,&val);
printf("出对元素:%d\n",val);
DeQueue(&queue,&val);
printf("出对元素:%d\n",val);
printf("对长:%d\n",QueueLength(&queue));
for(i=6;i<8;i++) EnQueue(&queue,i+1);
printf("对长:%d\n",QueueLength(&queue));
printf("对头元素:%d\n",GetTop(&queue));
printf("对尾元素:%d\n",GetRear(&queue));
return 1;
}
其中main函数就是模拟实现循环队列之后就能解决书上的问题了
未完待续: 下一章 二叉树算法一之创建和遍历
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权