文章目录

  • 一.环形队列的定义及其特点
  • 二.使用数组来实现环形队列
    • 1.创建一个队列
    • 2.初始化队列
    • 3. 判断环形队列是否为空
    • 4.判断环形队列是否已满
    • 5. 向循环队列插入元素,插入成功返回真
    • 6.删除环形链表的数据
    • 7. 取队头元素
    • 8.取队尾元素
    • 8.释放空间
  • 总结


一.环形队列的定义及其特点

循环队列是一种线性数据结构,其操作依然是先进先出原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

特点:

对于一个普通队列来说,每出队一次,头指针就必须往后移一位,这样使用过的空间就无法再重复使用,(头指针无法回移),即使队列元素小于队列大小,也无济于事,造成空间的浪费。

而对于循环队列来说,可以重复利用使用过的空间。解决了普通队列的问题。

基于循环队列的特点:我们可以使用数组或者循环链表来实现循环队列。

使用数组实现的话,尾指针到数组的大小时,回溯到头位置即可。

在这里给出一道题来实现环形队列。

二.使用数组来实现环形队列

首先,需要了解清楚的一件事是:如何判断环形队列的数据是否为空或者是否满了?

假如创建一个大小为4的环形队列,判断环形队列是否为空很简单,如果头指针和尾指针相等,则队列是空的,因为如果插入数据,尾指针一定往后移动。

环形队列插满数据是这样的:

此时头指针和尾指针指向的位置也是相同的!

所以当队列满队的时候无法区分是队空还是队满。

解决办法:

假如环形队列大小是k,我们就创建k+1大小的环形队列。

只需判断 (tail+1)%(k+1)是否等于head 即可。

1.创建一个队列

解读:对于普通队列来说,需要头指针和尾指针来维护入队和出队操作,入队时尾指针后移,出队时头指针后移。
在环形队列中也是如此。

以下代码中的head和front是一样的。


typedef struct
{int*a;int head;//队头int tail;//队尾,指向插入元素的下一个int k; //环形队列大小
} MyCircularQueue;

2.初始化队列

MyCircularQueue* myCircularQueueCreate(int k)
{MyCircularQueue*p = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));assert(p);p->a = (int*)malloc(sizeof(int)*(k+1));p->head = p->tail = 0;p->k = k; //环形队列大小return p;
}

开辟两块空间,一块空间是结构体的空间,一块空间是结构体的数组的空间。

3. 判断环形队列是否为空

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->head == obj->tail;
}

解读:环形队列是否为空就是判断头指针和尾指针是否相等,如果相等整个环形队列就为空,如果是其他情况,则环形队列至少有一个以上的数据。

4.判断环形队列是否已满

bool myCircularQueueIsFull(MyCircularQueue* obj) {if((obj->tail+1)%(obj->k+1) ==obj->head){return true;}return false;
}

判断环形队列是否已满,就是判断tail+1是否等于head,如果

5. 向循环队列插入元素,插入成功返回真

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj)){//满了return false;}obj->a[obj->tail] =value;//考虑特殊情况,如果插入之后tail是在外面,应该让tail回到0位置if(obj->tail+1 == obj->k+1) {obj->tail = 0;}  else{++obj->tail;}//也可以这样写// ++obj->tail;// obj->tail%=(obj->k+1);return true;
}

解读:

  1. 这里应该考虑的一种特殊情况是,假如插入的数据在环形队列的末尾,尾指针应该指向下一个位置,此时走出了数组的范围,所以需要回到数组0位置。
    2.如果环形队列满了,则不能再插入了。

6.删除环形链表的数据

bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return false;}//也是考虑特殊情况,如果删除后head在队列外面,则应让head回到0位置if(obj->head+1 == obj->k+1){obj->head = 0;}else{++obj->head;}//也可以这样写// ++obj->head;// obj->head%=obj->k+1;return true;
}
解读:
需要考虑特殊情况:特殊情况如下图:

7. 取队头元素

int myCircularQueueFront(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[obj->head];
}

8.取队尾元素

int myCircularQueueRear(MyCircularQueue* obj) {//取队尾元素有特殊情况,如果tail在0位置,那么需要返回//它的前一个,也就是第k个if(myCircularQueueIsEmpty(obj)){return -1;}if(obj->tail == 0){return obj->a[obj->k];}else{return obj->a[obj->tail-1];}//也可以这样写//return (obj->tail+obj->k)%(obj->k+1);
}

取队尾元素有一种特殊情况:

假如tail是在0位置,取队尾元素之后,tail需要回退到上一个位
置,即k+1位置处。

8.释放空间

void myCircularQueueFree(MyCircularQueue* obj) {//注意结构体有两层,需要先释放内层free(obj->a);obj->a = NULL;free(obj);
}

总结

环形队列在普通队列的基础上优化了空间重复利用问题,使空间利用率更高。
实际生活中使用队列的问题还是有很多的,比如营业厅,医院,银行的自动排队出票的机子,也是通过队列的先进先出的特点来实现的。

【数据结构】——环形队列相关推荐

  1. 数据结构——环形队列的原理(模拟环形队列)

    数据结构--环形队列的原理(模拟环形队列) 知识点简要介绍: 队列:一种特殊的线性表,包含队列头.队列尾,只允许在队列头进行删除操作,在队列为进行删除操作 分类:     顺序队列.循环队列(环形队列 ...

  2. 数据结构环形队列学习(c语言)

    数据结构环形队列学习(c语言) 实现效果 效果模型描述 代码设置队列长度为5,数组实际大小为6(队列长度加1) 黄色方格是队列头,灰色是未被使用内存,蓝色是队列元素 Example1: 当队列添加满元 ...

  3. 数据结构--环形队列的介绍与实现

    数据结构--环形队列实现 一.环形队列实现原理 环形队列的几个判断条件 二.代码实现 1.环形队列类(CircleQueue) 2.环形队列类测试类 3.程序运行结果 4.完整代码 环形队列可以用数组 ...

  4. 数据结构-环形队列 C和C++的实现

    队列: 含义:是一种先入先出(FIFO)的数据结构. 当我们把数据一个一个放入队列中.当我们需要用到这些数据时,每次都从队列的头部取出第一个数据进行处理.就像排队进场一样,先排队的人先进场. 结构如下 ...

  5. C语言数据结构——环形队列

    队列都有两个指针,分别指向队头和队尾,用于出队入队 这里使用顺序表来实现队列,设置头元素下标为front,指向队头,尾元素下标为rear,指向队尾的下一个节点.之所以不选择链表,是因为链表不便于查找队 ...

  6. 数据结构 - 环形队列

    关注 "弋凡"(YiFan)微信公众号吧 记录简单笔记 做你的最爱 环形队列图 思路: 1,front变量,初始值为 0,指向队列的第一个元素也是待取出的数据, 也就是说arr[f ...

  7. 数据结构--环形队列

    一.环形队列的概念: 1.使用数组模拟队列,空间只能使用一次,不能重复利用.浪费空间. 2.使用环形队列可以重复使用.节省空间 二.循环队列图解:  三.数组模拟环形队列思路: 1.首先front和r ...

  8. c++ 优先队列_数据结构 | TencentOStiny中队列、环形队列、优先级队列的实现及使用...

    1. 什么是队列 队列(queue)是一种只能在一端插入元素.在另一端删除元素的数据结构,遵循「先入先出」(FIFO)的规则. 队列中有两个基本概念: 队头指针(可变):永远指向此队列的第一个数据元素 ...

  9. 环形队列的输出_Java数据结构:使用数组实现环形队列详解

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

  10. 数据结构上机实践第七周项目1 - 自建算法库——顺序环形队列

    自建算法库--顺序环形队列 本次实践将建立顺序环形队列的算法库,用于之后的工程中 实现源代码如下: 1.squeue.h /* copyright (t) 2017,烟台大学计算机学院 *All ri ...

最新文章

  1. 开3389后不能登录的六种原因
  2. Java 垃圾回收机制概念梳理
  3. boost::mp11::mp_push_back相关用法的测试程序
  4. Nginx反向代理之proxy_set_header指令
  5. golang模板语法
  6. 周小川:数字人民币不会取代美元 也不会威胁全球货币体系
  7. 数据库设计中一个矛盾:数据库外键,用还是不用?你怎么看.?
  8. python的常量_如何给python中设定常量
  9. 数据链路层的差错控制ARQ
  10. python--re模块
  11. java基础学习及总结
  12. php正则可以实现模糊匹配,正则表达式的模糊匹配功能如何实现
  13. 用浏览器轻松录制音频、视频—— MediaRecorder API
  14. 阿里2019社招内推!阿里云高级专家(P8)帮内推!投递简历邮箱看正文!
  15. cmd 连接 远程数据库
  16. 君子爱财,取之有道!(租房被坑记)
  17. Tensorflow C++使用ops::BatchMatMul实现特征批量乘法
  18. kali下载中文输入法
  19. 实战:为图片生成文本摘要
  20. CentOS7安装可移植Prometheus+grafana--pushgateway及自定义监控

热门文章

  1. 怎么学好python?
  2. Android集成百度语音识别
  3. 音视频学习-h264的NALU结构分析
  4. 【服务器管理】搭建FTP
  5. 【高等数学】伽马函数与斯特林公式
  6. 手撕内存拷贝函数 memmove、memcpy
  7. STM32的推挽输出和开漏输出
  8. C# 经常忘 该记记
  9. Android 安装apk流程,Android PMS(二)-Apk安装流程
  10. iconfont 在原有的图标中,增加新的图标