【数据结构和算法】--队列的特殊结构-循环队列

这篇具有很好参考价值的文章主要介绍了【数据结构和算法】--队列的特殊结构-循环队列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

循环队列的结构

循环队列是队列的一种特殊结构,它的长度是固定的k,同样是先进先出,理论结构是首尾相连的环形循环结构。其理论结构大致如下:

【数据结构和算法】--队列的特殊结构-循环队列,数据结构和算法,数据结构,算法

具体结构描述可以参考LeetCode: 622. 设计循环队列的题目要求,大致如下:
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

循环队列的实现

循环队列的实现方式同样有两种–数组,链表

  1. 数组循环队列:
    数组实现方式顾名思义就是动态开辟一个长度为k的数组,那要怎么达到循环呢?我们可以定义两个数一个指向队列头元素int front),一个指向队列尾元素的下一个int back),(此处指向队尾下一个是为了方便队列空和满的判断),这样当back走到最后一个时,我们只需要将他重新置成0便又到了队列第一个元素,如此设计理论上就达到了循环结构。
    新的问题又来了:当front == back时要怎么区分队列是空还是满?两种解决方案:
  1. 增加一个size记录有效数据的节点数size == 0队列就是空,size == k队列就是满。
  2. 多开辟一个空间k+1front == back便是空,(back+1)%(k+1) == front就是满(即在理论结构中back指向的下一个位置是front,下文会讲解)。
  1. 链表循环队列:
    链表实现的循环队列更有点循环的味(即将尾指针的next指向头,形成真正的循环),但实现起来不如数组方便。链表实现循环队列同样要定义两个指针,一个指向循环队列的头元素(phead),一个指向循环队列尾元素的下一个(ptail)。判断循环队列空和满的方法和数组相似,只不过判断条件从判断值相同改为判断址相同,第二种方法判满改为phead == ptail->next
    但用链表设计循环队列也会有新的困难:1.获取循环队列尾元素不方便,还要遍历队列寻找;2. 定义结构体时,还要多定义一个装链表节点的结构体,这也增加了代码的难度。

所以不论是用数组还是用链表实现循环队列,都有各自的好处和问题,下面实现循环队列我所介绍的方法是数组实现法判满和判空用的是多定义一个节点法

依据上述方法,可以定义如下结构体变量:

typedef struct
{
    int* a;//数组
    int front;//队列头
    int back;//队列尾下一个位置
    int k;//循环队列可存储数据长度
} MyCircularQueue;

循环队列的创建

注意此处所给的函数返回值类型MyCircularQueue,正是上述结构体类型。故须先动态开辟一个结构体类型大小,并将frontback初始化为0,然后再利用结构体指针来开辟长度为k+1的数组最后返回结构体指针
这样动态开辟而不直接定义结构体变量(MyCircularQueue ps),是因为这是在函数中,出了函数的作用域此结构体变量就会销毁,所以需要malloc将结构体动态开辟在堆区。

MyCircularQueue* myCircularQueueCreate(int k)
{
    MyCircularQueue* ps = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    ps->a = (int*)malloc(sizeof(int)*(k+1));
    ps->back = ps->front = 0;
    ps->k = k;
    return ps;
}

循环队列为空判断

bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{
    return obj->front == obj->back;
}

循环队列为满判断

【数据结构和算法】--队列的特殊结构-循环队列,数据结构和算法,数据结构,算法

循环队列为满大致可以分为以上两种情况。

  1. 情况1:
    当队列尾back来到最后一个时,此时如果back + 1的话就会超过k + 1的范围,而我们的目的是想知道在循环队列中back + 1后的位置(即下标为0的位置),所以此时我们只要将(obj->back + 1)%(obj->k + 1),此式的值便为0
  2. 情况2:
    back + 1的范围在k + 1内,此时判断back + 1即可,若(obj->back + 1)%(obj->k + 1)也不会影响值。

如此将两式合并,便得到了简化的效果。

bool myCircularQueueIsFull(MyCircularQueue* obj)
{
    return (obj->back+1)%(obj->k+1) == obj->front;
}

入队

题目描述:enQueue(value):向循环队列插入一个元素。如果成功插入则返回真。
既如此那么先判断循环队列是否已满,若满则返回false,否则入队新值,并将obj->back值更新(obj->back %= obj->k+1;

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
    if(myCircularQueueIsFull(obj))
        return false;
    obj->a[obj->back] = value;
    obj->back++;
    obj->back %= obj->k+1;
    return true;
}

出队

题目描述:deQueue():从循环队列中删除一个元素。如果成功删除则返回真。
与入循环队列相似。

bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
    if(myCircularQueueIsEmpty(obj))
        return false;
    obj->front++;
    obj->front %= obj->k+1;
    return true;
}

返回循环队列首元素

题目描述:Front:从队首获取元素。如果队列为空,返回 -1 。
先判断循环队列不为空,若为空返回-1,不为空返回下标为obj->front的值。

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

返回循环队列尾元素

题目描述:Rear:获取队尾元素。如果队列为空,返回 -1 。
同样要先判断循环队列是否为空,为空返回-1。此处计算obj->back上一个的下标的方法中,obj->back-1后还要加obj->k+1是为了防止obj->back指向下标为0的情况,再% (obj->k+1)是为了防止超出下标范围的情况,与判断队满相似。

int myCircularQueueRear(MyCircularQueue* obj)
{
    if(myCircularQueueIsEmpty(obj))
        return -1;
    return obj->a[(obj->back-1+obj->k+1) % (obj->k+1)];
}

释放循环队列

依次释放即可,先释放最内层的数组,然后释放最外层的结构体。文章来源地址https://www.toymoban.com/news/detail-766128.html

void myCircularQueueFree(MyCircularQueue* obj)
{
    free(obj->a);
    free(obj);
}

到了这里,关于【数据结构和算法】--队列的特殊结构-循环队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 探索数据结构:特殊的双向队列

    探索数据结构:特殊的双向队列

    ✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:数据结构与算法 贝蒂的主页:Betty’s blog **双向队列(double‑ended queue)**是一种特殊的队列,它允许在队列的队尾与队头插入与删除元素。根据其定义,我们也可以理解为两个栈在栈底相连。

    2024年04月09日
    浏览(9)
  • 【数据结构与算法分析】使用C语言实现队列的两种(带头结点与不带头结点)链式存储,并且给出一种循环队列的设计思想

    【数据结构与算法分析】使用C语言实现队列的两种(带头结点与不带头结点)链式存储,并且给出一种循环队列的设计思想

      当我们编写程序时,经常需要处理各种数据结构。队列是一种常见的数据结构,它有着广泛的应用场景。队列的基本操作包括入队和出队,应用于模拟等待队列、消息队列、计算机缓存等场合。   在实际编程中,我们可以用不同的数据结构来实现队列。本文主要介绍了

    2024年02月08日
    浏览(204)
  • 数据结构--队列与循环队列

    数据结构--队列与循环队列

            队列是什么,先联想一下队,排队先来的人排前面先出,后来的人排后面后出;队列的性质也一样,先进队列的数据先出,后进队列的后出;就像图一的样子:  图1         如图1,1号元素是最先进的,开始出队时,那么他就是最先出的,然后12进队,就应该排在最

    2024年02月10日
    浏览(9)
  • 数据结构—循环队列(环形队列)

    数据结构—循环队列(环形队列)

    循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且 队尾被连接在队首之后以形成一个循环 。它也被称为“ 环形缓冲器 ”。 循环队列的一个好处是可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素

    2024年02月11日
    浏览(8)
  • 数据结构:循环队列的实现(leetcode622.设计循环队列)

    数据结构:循环队列的实现(leetcode622.设计循环队列)

      目录 一.循环队列简单介绍 二.用静态数组实现循环队列 1.数组循环队列结构设计 2.数组循环队列的堆区内存申请接口  3.数据出队和入队的接口实现 4.其他操作接口 5.数组循环队列的实现代码总览  三.静态单向循环链表实现循环队列  1.链表循环队列的结构设计 2.创建静态

    2024年02月03日
    浏览(8)
  • 数据结构--循环队列、链队

    //循环队列数据结构 typedef struct { QElemType data[MaxQSize];//数据域 int front,rear; //队头队尾指针 }SqQueue; //链队结点数据结构 typedef struct QNode { int data;//数据域 struct QNode* next;//指针域 }QNode, * QueuePtr; typedef struct { struct QNode* front, * rear;//rear指针指向队尾 用于入队 front指针指向队头 用于

    2024年02月15日
    浏览(17)
  • 数据结构——循环队列详解

    数据结构——循环队列详解

    目录 一、循环队列的定义 二、 循环队列的基本操作 三、循环队列的实现  1、循环队列的定义 2、循环队列的初始化  3、循环队列出队  4、循环队列入队  5、队列判空 6、 队列判满 7、取队头元素 8、输出队列  9、求队列长度  四、完整代码  五、小结  六、参考文献 一、

    2024年02月04日
    浏览(10)
  • 【数据结构】循环队列

    【数据结构】循环队列

    🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🐌 个人主页:蜗牛牛啊 🔥 系列专栏:🛹数据结构、🛴C++ 📕 学习格言:博观而约取,厚积而薄发 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与

    2024年02月12日
    浏览(12)
  • 数据结构——循环队列的实现

    数据结构——循环队列的实现

    hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥 个人主页:大耳朵土土垚的博客 💥 所属专栏:数据结构学习笔记 💥对于数据结构顺序表、链表、堆有疑问的都可以在上面数据结构的专栏进行学习哦~ 有问题可以写在评论区或者私信

    2024年03月24日
    浏览(9)
  • 九、数据结构——顺序队列中的循环队列

    九、数据结构——顺序队列中的循环队列

    一、循环队列的定义 二、循环队列的实现 三、循环队列的基本操作 ①初始化 ②判空 ③判满 ④入队 ⑤出队 ⑥获取长度 ⑦打印 四、循环队列的应用 五、全部代码 在数据结构中,队列(Queue)是一种常见的线性数据结构,遵循先进先出(First In First Out,FIFO)的原则。循环队

    2024年02月15日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包