队列
与之前说过的堆栈差不多
队列:具有一定操作约束的线性表
特点:先来先服务(先来现出栈)
数据对象集:一个有0个或多个元素的有穷线性表
操作集:
- 生成一定长度的队列
- 判断队列已满
- 插入队列
- 判断队列是否为空
- 把队列的头元素除
队列的顺序存储
用数组来进行存储,一个记录头元素位置的front 另一个记录尾元素的rear
队列的基本结构
struct queu{
int Data[Max];
int rear;//需要插入所以头
int front;//删除的时候操作所以尾
};
typedef struct queu *Q;
我们需要注意的是
front删除后往后移的量所以记作尾
rear插入的操作只用移动的量所以记作头
但是front记录的是头位置的前一位
rear记录的是尾位置的
如何判断是否为空,是否为满
我们通常可以看成这样
用一个变量n用来记录录入变量的个数
在此之前我们需要并上一个条件就是此时的
front == rear是否相等就有了这样的判断
if(rear==front && n==Max)//Max是最大的存储空间
否则如果不加入n这个变量用于计数的话我们就会发现
我们经过一系列的操作的时候我们无法清楚的知道
当rear==front的时候是空还是满!
同理
if(rear==front && n==0)//这个时候就为空了
这个时候就是队列为空的时候
如何让出去的元素让出位置让后面的数据输入到空出来的位置
就如小标题说的,我们会把其设计为循环的表,
顺环队列
如何实现在空的位置输入?我们就需要用到求余运算的思路
void input(int su,struct queu *Q,int n){//输入su个数字,已经存有n个数据
int m;
if (Q->rear==Q->front&&n>Max){
printf("满了嗷老铁!");
return;
}
else{
for (int i = 0; i < su; i++) {
scanf("%d",&m);
Q->Data[(++Q->rear)%Max]=m;//在余数中添加
}
}
}
void del(int n,struct queu*Q){//删除队列首个数据
if (Q->front==Q->rear&&n==0){
printf("队列空啦大哥");
}
else{
Q->Data[(++Q->front)%Max]=NULL;
}
}
我们可以看出求余的灵活应用
最后完整的队列模板
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define Max 5
struct queu{
int Data[Max];
int rear;//需要插入所以头
int front;//删除的时候操作所以尾
};
typedef struct queu *Q;
void input(int su,struct queu *Q,int n){//输入su个数字,已经存有n个数据
int m;
if (Q->rear==Q->front&&n>Max){
printf("满了嗷老铁!");
return;
}
else{
for (int i = 0; i < su; i++) {
scanf("%d",&m);
Q->Data[(++Q->rear)%Max]=m;//在余数中添加
}
}
}
void del(int n,struct queu*Q){//删除队列首个数据
if (Q->front==Q->rear&&n==0){
printf("队列空啦大哥");
}
else{
Q->Data[(++Q->front)%Max]=NULL;
}
}
void browse(struct queu*Q,int n){//浏览队列
int d=0;
printf("查看队列元素:\n");
for (int i = Q->front+1; d<n;d++) {
printf("它是:%d\n",Q->Data[(i+d)%Max]);
}
}
int main(){
Q AK;//定义AK是Q的结构体类型的
AK=(Q)malloc(sizeof(struct queu));//先申请一个存储空间
AK->front=-1;
AK->rear=-1;
int n=0;//用于记录
int s;//菜单选项
int su;//用于输入需要多少个数据
int ji=0;//用于计数的用于判断是否满队
while (1){
printf("请输入所需服务:\n");
printf("1.录入数据\n");
printf("2.从对列前端录入数据\n");
scanf("%d",&s);
switch (s) {
case 1:printf("请输入所需要输入多少个数据:");
scanf("%d",&su);
if (su>Max||(ji+su)>Max){
printf("你输入的数据过大!超出了包容范围!");
break;
}
n+=su;
ji=n;
input(su,AK,n);
break;
case 2:printf("删除第一个数据");
del(n,AK);
n--;//数据减少
ji=n;
break;
case 3:break;
case 4:browse(AK,n);
}
if (s==3)break;
}
return 0;
}
在此我添加了browse浏览队列的功能,用于清楚的看到当前输入多少数据帮助大家分析队列的结构和工作原理
总结:
- 求余运算我们可以用在循环体系里面
- 队列的实际应用问题,可以用于申请的批准等等
- 队列的缺点,必须等前面的解决完毕才轮到到后方的
- 我们需要着重注意标记n的含义和,front,rear变化后的含义
由于家里有一些事情连夜赶出来的笔记有需要指正的地方欢迎评论(做的还是有点潦草,这个是我个人对队列的理解及其编译出来后的模型,希望大家能够帮我指针糅杂的地方)