目录

一、队列简介

二、顺序队列

三、环形队列

四、环形队列代码

1、队列结构体

2、队列初始化

3、判断队列是否为满

4、判断队列是否为空

5、将数据插入到队列中

6、读取队列中的数据

7、释放队列空间

8、功能测试


一、队列简介

队列只允许在队列头(front)进行删除操作,在队列尾(rear)进行插入操作,当队列中没有元素时,称为空队列在队列中插入元素称为入队,从队列中删除元素称为出队。因为队列只允许在尾端插入,在头端删除,所以只有最早进入队列的元素才能最先从队列中删除,即队列有先进先出的特点。

二、顺序队列

即仅在队头进行删除在队尾进行插入,可用地址连续的存储单元依次存放队列中的数据,比如数组。队头和队尾的位置是变化的,所以要设置头、尾指针

初始化时的头尾指针,均置为 0。 当头尾指针相等时队列为空或者为满,在非空队列里,头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置。

由队列的原理可以将头指针当做读操作,将尾指针当做写操作,即在尾端插入数据就是写入队列,在头端删除数据就是将队列中的数据读出,这样好理解点。

刚开始头指针和尾指针都在同一位置

当队列入队时,尾指针加一,头指针保持不变,a1入队,尾指针rear+1指向下一个地址空间,即尾指针始终指向队尾的下一地址,如a4入队后,尾指针rear+1 。

队列出队时,尾指针保持不变,头指针依次加1,由先进先出原则,a1先入队,则a1先被读走,然后front+1,指向了 a2,a2删除后,front+1指向了 a3。

当a5删除后,头指针和尾指针的指向又相同相等了,即说明队列中的数据 已经全部读走

在顺序队列中,当尾指针已经指向了队列的最后一个位置的下一位置时,如果再有元素入队,就会发生“溢出”此时队列中已经填满了数据,头指针还在开始位置。

顺序队列的 “假溢出” :即队列的存储空间并未填满,却发生了溢出。

比如 rear 现在指向了最后一个位置的下一位置,按照上面所说此时队列已经被填满,如果再有元素入队,就会发生“溢出”,但这是在头指针没有移动的前提下,如果之前队列头也删除了一些元素,那么队列头指针经过n次的 +1 之后,会遗留下了很多空地址,但是顺序队列就会认为再有元素入队,就溢出,即出现 “假溢出” 现象,这是不合理的,故出现了环形队列

三、环形队列

环形队列的使用场景还是挺多的,比如要将单片机一些模块采集的数据连续上传到PC端,这里就可以用到环形队列,即将采集的数据放到队列中去,再将队列中的数据读出上传到PC端,这里为什么不直接将采集端和上传端直接相连呢?因为采集数据的速度和上传数据的速度是不知道的,如果直接相连会出错。

 环形队列的原理就是将新元素加入到第一个位置上,构成类似于一个环一样的队列,入队和出队还是按照“先进先出”的原则进行,环形队列的空间利用率高。

环形队列解决了顺序队列 “假溢出” 的现象,但是又出现新的问题,即怎么判断队列是否为空,如果单用 rear = front 判断空或满显然是不行的,比如

此时两种情况都是 rear = front 的情况,在环形队列中,当队列满了之后 rear + 1会指向第一个地址,即出现了  rear = front 的情况。

一般判断队列空的条件是 rear = front, 通常少用一个元素的储存空间用来判断队列是否满,即在入队前测试尾指针加 1 后是否等于头指针,若相等则认为队满。

或者当用数组array[len]来表示队列时,则可用(rear - front)的差和数组长度 len 进行比较,如果相等则说明队列已满,(在下面说明这种方法)。

四、环形队列代码

 W等于尾指针rear,R等于头指针front,相当于写操作读操作

1、队列结构体

/*队列结构体*/
typedef struct ring_buff{int array[len]; int W;int R;
}*ring;

2、队列初始化

/*队列初始化*/
struct ring_buff *fifo_init(void)
{struct ring_buff *p = NULL;p = (struct ring_buff *)malloc(sizeof(struct ring_buff));if(p == NULL){printf("malloc error\n");return -1;}else{p->W = 0;p->R = 0;memset(p->array,0,sizeof(p->array));return p;}
}

将队列相应空间清零。

3、判断队列是否为满

/*判断是否满*/
int get_ring_buff_fullstate(struct ring_buff *P_ring_buff)
{if((P_ring_buff->W - P_ring_buff->R) == len){return 1;}else{return 0;}
}

如上图所示,array[6] 的存储空间为array[0] - array[5],即6个数,当RW等于0时指向array[0],存入数据后W++,指向下一个地址,当W将array[5]存入数据后会自加一,此时W = 6,R = 0,下一次判断队列是否满时条件成立,即W  -   R  =  len,len为数组长度6

4、判断队列是否为空

/*判断是否为空*/
int get_ring_buff_emptystate(struct ring_buff *P_ring_buff)
{if(P_ring_buff->W == P_ring_buff->R){return 1;}else{return 0;}
}

当头指针和尾指针相等时判断为空

5、将数据插入到队列中

/*插入数据*/
int ring_buff_insert(struct ring_buff *P_ring_buff,int data)
{if(P_ring_buff == NULL){        printf("insert P_ring_buff error\n");return -1;}/*判断队列是否满*/if(get_ring_buff_fullstate(P_ring_buff) == 1){printf("full\n");return -1;}P_ring_buff->array[P_ring_buff->W%len] = data;P_ring_buff->W++;return 0;
}

W = {0、1、2、3、4、5 },则array[W%len] = {0、1、2、3、4、5},刚好依次对应,当W = 6时,6 % 6 = 0,又从array[0]开始存储数据,这也是环形队列的关键,即形成闭环。

6、读取队列中的数据

/*读取数据*/
int ring_buff_get(struct ring_buff *P_ring_buff)
{int data = 0;if(P_ring_buff == NULL){printf("get P_ring_buff error\n");return -1;}data = P_ring_buff->array[P_ring_buff->R%len];P_ring_buff->R++;return data;
}

读取数据和写入数据类似,也是当R = 6时,6 % 6 = 0,又从array[0]开始读取数据

7、释放队列空间

/*销毁*/
int ring_buff_destory(struct ring_buff *P_ring_buff)
{if(P_ring_buff == NULL){printf("destory P_ring_buff error\n");return -1;}free(P_ring_buff);return 0;
}

8、功能测试

#define len 6
int main()
{int i;int getData = 0;
/*初始化队列*/ring Pt_ring_buff = fifo_init();
/*向队列中写数据,即0 - 5*/for(i = 0;i < 6;i++){ring_buff_insert(Pt_ring_buff,i);}
/*将写入的数据读出三个,由先进先出原则应该读的0 - 2*/for(i = 0;i < 3;i++){printf("  %d",ring_buff_get(Pt_ring_buff));}printf("\n");
/*再写入三个数据,此时写入的数据应该在上面的数据之后,即在5之后*/for(i = 8;i < 11;i++){ring_buff_insert(Pt_ring_buff,i);}
/*读取队列中的数据,此时再次读取队列中的数据时,0 - 2 已经被读走,所以应该是从3、4、5、8、9、10、3 ...循环读取十个数据*/    for(i = 0;i < 10;i++){printf("  %d",ring_buff_get(Pt_ring_buff));}ring_buff_destory(Pt_ring_buff);   //释放空间printf("\n");system("pause");return 0;
}

输出结果

常用数据结构 ——— 队列(环形队列和顺序队列)相关推荐

  1. 数据结构之基于Java的顺序队列实现

    本文的代码来自于<数据结构与算法(JAVA语言版)>,是笔者在网上找到的资料,非正式出刊版物.笔者对代码一些比较难以理解的部分添加了注释和图解,欢迎大家来讨论. 重点理解通过取余运算将线性 ...

  2. java编程 队列_5.1、顺序队列(java实现)

    public classSeqQueue {private final int MaxSize = 8;private int rear; //队尾指针 private int front; //队头 ...

  3. Java数据结构(1.1):数据结构入门+线性表、算法时间复杂度与空间复杂度、线性表、顺序表、单双链表实现、Java线性表、栈、队列、Java栈与队列。

    数据结构与算法入门 问题1:为什么要学习数据结构          如果说学习语文的最终目的是写小说的话,那么能不能在识字.组词.造句后就直接写小说了,肯定是不行的, 中间还有一个必经的阶段:就是写作 ...

  4. 数据结构(二):线性表包括顺序存储结构(顺序表、顺序队列和顺序栈)和链式存储结构(链表、链队列和链栈)...

    还记得数据结构这个经典的分类图吧: 今天主要关注一下线性表. 什么是线性表 线性表的划分是从数据的逻辑结构上进行的.线性指的是在数据的逻辑结构上是线性的.即在数据元素的非空有限集中 (1) 存在唯一的 ...

  5. 队列(常用数据结构之一)

    队列 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除 ...

  6. C语言数据结构-第三章栈和队列-电大同步进度

    第三章栈和队列简介 从数据结构角度看,栈和队列是两种重要的线性结构,是一类操作受限制的特殊线性表,其特殊性在于限制插入和删除等运算的位置. 堆栈,限制用户只能在指定的一端插入和删除元素,因此具有后进先 ...

  7. c语言建立队列(顺序队列、循化队列和链式队列)

    c语言建立队列 一.顺序队列 队列的顺序存储结构 顺序队列的讨论 "下溢"现象 "真上溢"现象 "假上溢"现象 二.如何解决"假上 ...

  8. 数据结构Python版(四)——队列

    目录 一.队列简介 二.顺序队列 2.1 非循环队列 2.2 循环队列 2.2.1 假溢出 2.2.2 循环队列的架构 2.2.3 循环队列的实现 三.链队 3.1 链队的完整实现 四.双端队列 4. ...

  9. (PTA)数据结构(作业)6、队列

    栈是后进先出的线性表(Last In First Out,LIFO),插入和删除的操作都在栈顶进行. 队列是先进先出的线性表(First In First Out,FIFO),插入在队尾进行,删除在队 ...

最新文章

  1. 第一篇:时间和全局状态
  2. 数据系列:如何在Windows Azure虚拟机上设置SQL Server
  3. python的with用法(参考)
  4. 三面腾讯,竟然挂在了JVM上…
  5. android中变量作用域,在 Android 和 Hilt 中限定作用域
  6. AM335X 分配大于4M的framebuffer
  7. 滴滴笔试准备 项目分配利益最大化
  8. 初始化对于类与接口的异同点深入解析
  9. SDNU 1170.津津的储蓄计划
  10. mysql_affected_rows()、mysql_fetch_row、mysql_fetch_assoc
  11. javaee7实现websocket_websocket协议,tcp分包与粘包解决
  12. 药企如何应对计算机系统验证?浪潮GMP管理保驾护航
  13. 笔记本电脑里计算机未响应,浅析笔记本win7系统下Word程序总是未响应的原因及解决办法【图文】...
  14. ORACLE通过身份证号计算年龄
  15. 常见手机病毒学习总结
  16. 问答网站Stack Overflow的成功之道
  17. 线程安全问题和解决方法
  18. 修改mac地址导致计算机无法上网,win7系统更换MAC地址解决无法连接网络问题的解决方法...
  19. C4D模型工具—优化
  20. 由浅入深学习Flash制作赛车游戏教程

热门文章

  1. 蓝桥杯 LQ三角形 模拟
  2. Java 多线程编程核心技术
  3. python自动购买12306票_Python-12306模拟自动购票!快过年了,学起来啊!
  4. DSP6678串口(UART)使用学习
  5. ES6 Array every()实例讲解
  6. css实现彩色渐变滑动条
  7. centos新系统新挂载原硬盘方法
  8. Linux/Centos 7 系统硬盘扩容、挂载
  9. React-Canvas画图
  10. H5 通过exceljs,根据模板替换内容,导出xlsx文件