队列,和栈一样,也是一种对数据的"存"和"取"有严格要求的线性存储结构。

什么是队列

与栈结构不同的是,队列的两端都"开口",要求数据只能从一端进,从另一端出,如下图示:

通常,称进数据的一端为 "队尾",出数据的一端为 "队头",数据元素进队列的过程称为 "入队",出队列的过程称为 "出队"。

不仅如此,队列中数据的进出要遵循 "先进先出" 的原则,即最先进队列的数据元素,同样要最先出队列。拿图 1 中的队列来说,从数据在队列中的存储状态可以分析出,元素 1 最先进队,其次是元素 2,最后是元素 3。此时如果将元素 3 出队,根据队列 "先进先出" 的特点,元素 1 要先出队列,元素 2 再出队列,最后才轮到元素 3 出队列。

栈和队列不要混淆,栈结构是一端封口,特点是"先进后出";而队列的两端全是开口,特点是"先进先出"。
因此,数据从表的一端进,从另一端出,且遵循 "先进先出" 原则的线性存储结构就是队列。

顺序队列的实现

顺序队列,即采用顺序表模拟实现的队列结构。

我们知道,队列具有以下两个特点: 数据从队列的一端进,另一端出; 数据的入队和出队遵循"先进先出"的原则;

因此,只要使用顺序表按以上两个要求操作数据,即可实现顺序队列。首先来学习一种最简单的实现方法。

顺序队列简单实现

由于顺序队列的底层使用的是数组,因此需预先申请一块足够大的内存空间初始化顺序队列。除此之外,为了满足顺序队列中数据从队尾进,队头出且先进先出的要求,我们还需要定义两个指针(top 和 rear)分别用于指向顺序队列中的队头元素和队尾元素,如下图所示:

由于顺序队列初始状态没有存储任何元素,因此 top 指针和 rear 指针重合,且由于顺序队列底层实现靠的是数组,因此 top 和 rear 实际上是两个变量,它的值分别是队头元素和队尾元素所在数组位置的下标。

在上图的基础上,当有数据元素进队列时,对应的实现操作是将其存储在指针 rear 指向的数组位置,然后 rear+1;当需要队头元素出队时,仅需做 top+1 操作。

例如,在上图的基础上将{1,2,3,4}用顺序队列存储的实现操作如下图所示:

在上图基础上,顺序队列中数据出队列的实现过程如下图所示:

因此,使用顺序表实现顺序队列最简单方法的 C 语言实现代码为:

#include <stdio.h>
int enQueue(int *a,int rear,int data){a[rear]=data;rear++;return rear;
}
void deQueue(int *a,int front,int rear){//如果 front==rear,表示队列为空while (front!=rear) {printf("出队元素:%dn",a[front]);front++;}
}
int main() {int a[100];int front,rear;//设置队头指针和队尾指针,当队列中没有元素时,队头和队尾指向同一块地址front=rear=0;//入队rear=enQueue(a, rear, 1);rear=enQueue(a, rear, 2);rear=enQueue(a, rear, 3);rear=enQueue(a, rear, 4);//出队deQueue(a, front, rear);return 0;
}

程序输出结果:

出队元素:1 出队元素:2 出队元素:3 出队元素:4

此方法存在的问题

先来分析上面两张图。第一张图的b是有数据进队成功的示意图,而第二张图的b 是所有数据全部出队后的示意图。通过对比两张图,你会发现,指针 top 和 rear 重合位置指向了 a[4] 而不再是 a[0]。也就是说,整个顺序队列在数据不断地进队出队过程中,在顺序表中的位置不断后移。

顺序队列整体后移造成的影响是: - 顺序队列之前的数组存储空间将无法再被使用,造成了空间浪费; - 如果顺序表申请的空间不足够大,则直接造成程序中数组 a 溢出,产生溢出错误;

为了避免以上两点,我建议初学者使用下面的方法实现顺序队列。

顺序队列另一种实现方法

既然明白了上面这种方法的弊端,那么我们可以试着在它的基础上对其改良。

为了解决以上两个问题,可以使用巧妙的方法将顺序表打造成一个环状表,如下图所示:

上图只是一个想象图,在真正的实现时,没必要真创建这样一种结构,我们还是使用之前的顺序表,也还是使用之前的程序,只需要对其进行一点小小的改变:

#include <stdio.h>
#define max 5//表示顺序表申请的空间大小
int enQueue(int *a,int front,int rear,int data){//添加判断语句,如果rear超过max,则直接将其从a[0]重新开始存储,如果rear+1和front重合,则表示数组已满if ((rear+1)%max==front) {printf("空间已满");return rear;}a[rear%max]=data;rear++;return rear;
}
int  deQueue(int *a,int front,int rear){//如果front==rear,表示队列为空if(front==rear%max) {printf("队列为空");return front;}printf("%d ",a[front]);//front不再直接 +1,而是+1后同max进行比较,如果=max,则直接跳转到 a[0]front=(front+1)%max;return front;
}
int main() {int a[max];int front,rear;//设置队头指针和队尾指针,当队列中没有元素时,队头和队尾指向同一块地址front=rear=0;//入队rear=enQueue(a,front,rear, 1);rear=enQueue(a,front,rear, 2);rear=enQueue(a,front,rear, 3);rear=enQueue(a,front,rear, 4);//出队front=deQueue(a, front, rear);//再入队rear=enQueue(a,front,rear, 5);//再出队front=deQueue(a, front, rear);//再入队rear=enQueue(a,front,rear, 6);//再出队front=deQueue(a, front, rear);front=deQueue(a, front, rear);front=deQueue(a, front, rear);front=deQueue(a, front, rear);return 0;
}

程序运行结果:

1 2 3 4 5 6

使用此方法需要注意的是,顺序队列在判断数组是否已满时,出现下面情况: - 当队列为空时,队列的头指针等于队列的尾指针; - 当数组满员时,队列的头指针等于队列的尾指针;

顺序队列的存储状态不同,但是判断条件相同。为了对其进行区分,最简单的解决办法是:牺牲掉数组中的一个存储空间,判断数组满员的条件是:尾指针的下一个位置和头指针相遇,就说明数组满了,即程序中第 5 行所示。

不去追逐,永远不会拥有。不往前走,永远原地停留!

利用本篇文章的机会,给大家介绍了C队列以及简单的实现了顺序队列,并作出了一些优化。相关的代码依旧是托管在了github上面,需要的小伙伴请自取。如果有写的不好的地方,大家在评论区留言,我加以改正,和大家一起共同进步!

北徯的博客​www.xiangjunhong.com

顺序队列为空的条件_C语言实现顺序队列相关推荐

  1. 【Golang第6章:排序和查找】golang怎么排序,golang的顺序查找和二分查找,go语言中顺序查找二分查找介绍和案例

    介绍 这个是在B站上看边看视频边做的笔记,这一章是GO语言的排序和查找 有golang怎么排序,golang的顺序查找和二分查找,go语言中顺序查找二分查找介绍和案例,具体请看[文章目录] 配套视频自 ...

  2. c语言栈的实现以及操作_C++语言实现顺序栈

    在写C语言实现顺序栈的时候,我已经向大家介绍了栈的特点以及介绍了栈的相关操作,并利用C语言实现了相关算法.在这里小编就不在继续给大家介绍了,需要温习的可以看看之前的文章,下面是链接C语言实现顺序栈在这 ...

  3. 顺序队列为空的条件_合成中心丙烯压缩空冷器冬季防冻及自动化运行项目顺利完成...

    技术创新 合成中心 合成中心创新工作室自成立以来,紧紧围绕中心年度重点工作,全面盘点当前制约高负荷生产的主要问题,分析原因,申报创新课题.合成中心在创新活动中秉承课题不求大但求实,以全员参与.落实精细 ...

  4. c语言设计程序实现顺序冒泡_C语言学习 顺序程序设计

    1.常量和变量 A.常量 (1)整型常量 (2)实型常量 a十进制小数形式 b指数形式 (3)字符常量 a普通字符:用单撇括起来的一个字符,如`a`,`Z`,'3' b转义字符 (4)字符串常量:如& ...

  5. 栈和队列:2.队列(Queue)及其C语言实现

    队列是线性表的一种,在操作数据元素时,和栈一样,有自己的规则:使用队列存取数据元素时,数据元素只能从表的一端进入队列,另一端出队列,如图1. 图1 队列示意图 称进入队列的一端为"队尾&qu ...

  6. c语言模拟多级反馈队列调度算法实验报告,多级反馈队列调度算法的实现-20210323055826.docx-原创力文档...

    This model paper was revised by LINDA on December 15, 2012. This model paper was revised by LINDA on ...

  7. 顺序表的c语言结构体描述,顺序表的基本方法实现C语言版

    顺序表--------------线性表的第一个儿子 这个儿子的结构体定义: typedef int ElemType;//取别名 typedef struct link{ ElemType * he ...

  8. 环形队列出队的元素怎么输出出来_队列的知识讲解与基本实现(数据结构)

    引言 中午在食堂打饭,真是一个令人头疼的事情,去食堂的路上也总是步伐匆匆,为什么啊,这还用说,迟一点去,你就会知道什么叫做人山人海了,在食堂排队的时候,相比较学生来说,打饭阿姨毕竟是少数,在每个窗口都 ...

  9. 不可上位!数据结构队列,老实排队,Java实现数组模拟队列及可复用环形队列

    文章目录 队列简介 数组模拟队列(无法复用) 数组模拟环形队列(可复用) 队列简介 队列是一个有序列表,可以用数组或是链表来实现. 遵循先入先出的原则.即先存入队列的数据,先取出,后存入的后取出. 示 ...

  10. java数据结栈空的条件表达式_数据结构——栈和队列例题

    1.若一个栈的输入序列为1,2,3,-,n,输出序列的第一个元素是i,则第j个输出元素是_____. 选项ABCD均错误,第j个输出元素应为i-j+1. 栈是一种先进后出的数据结构,也就是说如果入栈顺 ...

最新文章

  1. Ozon Tech Challenge 2020 (Div.1 + Div.2) E.Kuroni and the Score Distribution 构造
  2. 奇妙的安全旅行之ECC算法
  3. matlab将列数据存成excel表格,matlab将列数据存成excel表格-matlab工作区数据怎么转为excel...
  4. MYSQL执行计划EXPLAIN
  5. C++ 调试配置的项目设置
  6. 深入剖析 redis 主从复制
  7. (好文章搬个砖)MySQL索引背后的数据结构及算法原理
  8. 大创(国创)国家级最新模板资料分享大学生创新创业训练项目怎么准备模板参考学习立项结题报告中期检查报告申报书的创新点和项目特色流程表结项任务书阶段性报告验收表实施心得成果怎么写报了大创需要准备什么做什么
  9. Windows字符和字符串处理
  10. Premiere Pro CS6自学所需的视频编辑基础(二)
  11. javascript音乐播放器
  12. DDR 内存基础知识(2)- DDR预取
  13. 思科服务器的dns如何配置文件,思科在服务器上配置dns
  14. a55计算机主板,高性价比APU主板!AMD A55主板对比评测
  15. 竞态条件的赋值_信号-sunshine225-51CTO博客
  16. 广州市白云区2021-2022学年九年级第一学期期末考试英语试题
  17. react-native集成极光推送
  18. 教学资源管理软件PHP,应用ThinkPHP框架的教学资源科研管理平台设计研究
  19. 计算机相关双人相声,适合学生表演的双人相声剧本
  20. 【python爬虫】HIMCM2016 FedEx联邦快递的一日达地图

热门文章

  1. JProfiler分析内存泄漏
  2. 用new/delete动态创建数组| 一维/二维/三维
  3. JavaSE中容易忽视的坑
  4. 一些Gym三星单刷的比赛总结
  5. [Hdu3555] Bomb(数位DP)
  6. ipsec over gre与gre over ipsec
  7. Provisioning Services 7.8 入门系列教程之四 目标设备安装
  8. 检查Mysql引擎的方法
  9. 多线程Socket传送文件的客户端和服务端源代码
  10. IDEA 配置-XX:-RestrictContended参数