目录
一、队列的定义
队列只能在一端插入,另一端删除,插入的一端叫队尾(rear),删除的一端叫队首(front)。
队列最大的特点就是先进先出,可以理解为在食堂排队打饭,第一个排队的最先在d出去。
二 、真溢出与假溢出
溢出就是队列满了,判断队空和队满的条件为:
队空:front=rear
队满:rear-front=maxsize
当rear在队首,front在队尾时,也就是front指向0,rear指向4,此时队满,不能再入队列。这种情况是真溢出。
当rear在队首,front在rear后一个时,也就是front指向3,rear指向4,此时虽然有队列中有空间,但也不能再入队列。这种情况是假溢出。
三、解决假溢出
将队列首尾相连,形成一个圆环,并且称这种队列为循环队列。
圆环的情况下,队空时front=rear,队满时front=rear,两种情况就冲突了。
此时需要牺牲一个空间,用于区别队空和队满。判断队空,队满的条件变为:
队空:front == rear
队满:(rear+1)%maxsize == front
当rear=5,front=0
(rear+1)%6=0=front,队满
四、注意
在入队和出队时,front和rear不能单纯的只+1,要写为:
frount = (frount + 1) % maxsize
rear = (rear + 1) % maxsize
这是为了保证front和rear指针能够正确的指示队列头尾元素在数组内的位置,需要在进行入队和出队操作时对 front和rear 进行加减1的操作。比如rear指向5时,如果再+1就指向了6,就错误了,如果+1再与maxsize(6)取余,成功指向0。
五、代码
#include<stdio.h>
#include<stdlib.h>
typedef struct sqqueue
{
int* base;
int frount;
int rear;
}sqqueue;
//maxsize为10,数字更直观
//全局声明
sqqueue Q;
//创建队列
int createsqueue(sqqueue& Q)
{
Q.base = (int*)malloc(sizeof(int) * 10);
if (Q.base == NULL)
{
printf("分配内存失败!");
exit(1);
}
Q.frount = Q.rear = 0;
printf("创建成功!\n");
return 0;
}
//入队列
int insqqueue(sqqueue& Q,int e)
{
if ((Q.rear + 1) % 10 == Q.frount)
{
printf("队满!\n");
exit(1);
}
Q.base[Q.rear] = e;
printf("%d入队成功!\n", e);
Q.rear = (Q.rear + 1) % 10;
return 0;
}
//出队列
int outsqqueue(sqqueue& Q)
{
if (Q.frount == Q.rear)
{
printf("队空!\n");
exit(1);
}
int e = 0;
e = Q.base[Q.frount];
printf("%d出队成功!\n", e);//不是真正的删除数据,是另找一个空间存储他
Q.frount = (Q.frount + 1) % 10;
return 0;
}
//取队头元素
int gethead(sqqueue& Q)
{
if (Q.frount == Q.rear)
{
printf("队空!");
exit(1);
}
printf("队头元素为:%d\n",Q.base[Q.frount]);
return 0;
}
//求队长
int queuelength(sqqueue& Q)
{
printf("此时队长为:%d\n", Q.rear - Q.frount);
return 0;
}
//菜单
void menu(void)
{
printf("******************************\n");
printf("*** 1---创建队列 ****\n");
printf("*** 2---入队 ****\n");
printf("*** 3---出队 ****\n");
printf("*** 4---取对头元素 ****\n");
printf("*** 5---求队长 ****\n");
printf("******************************\n");
}
//主函数
int main(void)
{
int choice, e, t;
menu();
while (1)
{
printf("请选择功能:");
scanf("%d", &choice);
switch (choice)
{
case 1:
t = createsqueue(Q);
break;
case 2:
printf("请输入需要入队的数:");
scanf("%d", &e);
t = insqqueue(Q, e);
break;
case 3:
t = outsqqueue(Q);
break;
case 4:
t = gethead(Q);
break;
case 5:
t = queuelength(Q);
break;
}
}
return 0;
}