由于普通队列出现了假溢出的问题,我们使用循环队列的方式解决这个问题
假溢出:当rear=maxsize时,front为任意下标t(t!=0),此时队列被判定已满,但是在下标t之前的位置,也就是下标小于t的位置理论上还可以存放元素
如何实现循环队列:
循环队列初始形态:rear=front=0
循环队列入队:rear=(rear+1)%maxsize
循环队列出队:front=(front+1)%maxsize
循环队列长度:(rear-front+maxsize)%maxsize 注:这里的front不指向元素
若对于每一块位子都用来存放元素的循环队列,判空判满:
判空:rear=front
判满的话无法判断因为如果你要写rear=front判空的话,因为rear=(rear+1)%maxszie所以队列为满也会出现rear=front
为了解决这个问题,我们提出三种方案:
1,空出一块位置不放元素用来区分队空队满,这样的话
队空:rear=front 队满:(rear+1)%maxsize=front (为什么写成这个呢,因为之前的话,没有空出一块位置,rear一直指向的都是队列中最后一个元素的下一块位置,我们假设rear一直加front不动,rear加到maxszie-1时,此时再进行入队则为队满,rear=(rear+1)%maxszie,所以此时的rear=0=front因此被判为队空是错误的,而此时我们空出了一个位置,rear指向的位置为队列中的最后一个元素,还是假设rear一直加front不动,当rear加到maxsize-1时判定条件front=(rear+1)%maxszie成立,判定为队满,由于rear指向的为队列中最后一个元素,此时确实为队满,完美解决问题)
2,类型中增设size成员,表示元素个数,删除成功size减一,插入成功size加一,队空状态size=0,队满状态size=maxsize,两种情况都会出现rear=front
3,类型中增设tag数据成员,删除成功tag=0,若导致了front=rear则为队空,插入成功tag=1,若导致了rear=front则为队满
//以下是我写的第一种方法的一些函数,主函数写的并不好,可以自行完善一下
#include <stdio.h>
#define maxsize 10
typedef struct queue{
int data[maxsize];
int front,rear;
}squeue;
squeue p;
//初始化
void initqueue(squeue &p)
{
p.front=p.rear=0;
}
//判空
bool emptyqueue(squeue p)
{
if (p.front==p.rear) return true;
return false;
}
//判满
bool manqueue(squeue p)
{
if(p.front==(p.rear+1)%maxsize) return true;
return false;
}
//入队
bool push(squeue &p,int x)
{
//先判满
if(manqueue(p))
{
printf("队列已满\n");
return false;
}
//rear先往后移动一位,然后再插入,这样就可以让rear指向最后一个元素,空出一块位置
p.rear=(p.rear+1)%maxsize;
p.data[p.rear]=x;
return true;
}
//出队
bool pop(squeue &p,int &x)
{
//先判空
if(emptyqueue(p))
{
printf("队列为空\n");
return false;
}
//由于front指向第一个元素的前一块空位置,所以我们先移动front再删除就可以既能删掉元素又能移动front到删除完之后的第一个元素的前一块空位置
p.front=(p.front+1)%maxsize;
x=p.data[p.front];
return true;
}
int main()
{
int x,y,l;
//初始化
initqueue(p);
//入队
while(1)
{
printf("输入你要入队的元素值:");
scanf("%d",&x);
int j=push(p,x);
if(j!=0)
{
printf("插入了第%d个元素,元素值为%d\n",p.rear,x);
}
if(j==0) break;
}
//出队
while(l!=9999)
{
int k=pop(p,y);
if(k!=0) printf("删除了队列中第%d个元素,元素值为%d\n",p.front,y);
if(k==0) break;
printf("是否继续删除:输入9999结束");
scanf("%d",&l);
}
}