【数据结构】循环队列

简介: 文章目录📑前言🍁一、循环队列的结构💭 二、循环队列的操作1.定义循环队列2.创建循环队列3.判断满

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤

📃个人主页 :阿然成长日记 👈点击可跳转

📆 个人专栏: 🔹数据结构与算法🔹C语言进阶

🚩 不能则学,不知则问,耻于问人,决无长进

🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

📑前言

在上一篇博客当中我们使用了单链表的形式来模拟队列,你会发现,当执行入队列操作时,我们动态开辟了许多的节点,在元素出队列时,我们进行大量头删,释放内存等操作。实际上浪费了许多的空间与时间。

顺序队列在使用过程中容易出现虚假的满状态, 为了解决这个问题,就产生了一个较巧妙的方法,将顺序队列臆造为一个环状的空间,称之为循环队列。循环队列中指针和队列元素之间的关系不变,我们只需要利用模运算就可以很容易实现指针的循环移动。但是循环队列中存在一个问题,在循环队列中只凭头指针front等于尾指针rear无法判别队列空间是“空”还是“满”,可有两种处理方法:其一是另设一个标志位以区别队列是“空”还是“满”;其二是少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(指环状的下一位置)上”作为队列呈“满”状态的标志。

🍁一、循环队列的结构

循环队列的结构建议使用数组,它能更好的利用空间与位置,便于指针的循环。

假定:此队列最大容纳MaxSize个元素。

为了更好的区分空和满。循环队列最后一个空间第MaxSize+1位置保证为空NULL;

💭 二、循环队列的操作

1.定义循环队列

//定义循环队列 
typedef struct MyCircularQueue
{
  int* a;//数组
  int front;//头
  int rear;//尾
  int MaxSize;//队列最大容量
}MCQueue;

2.创建循环队列

注意:创建数组,MaxSize + 1,多开辟一个空间。

//创建循环队列
MCQueue* MCQueueCreat(int MaxSize)
{
  //创建队列结构
  MCQueue* obj = (MCQueue*)malloc(sizeof(MCQueue));
  //创建数组,MaxSize + 1,多开辟一个空间。
  obj->a = (int*)malloc(sizeof(int) * (MaxSize + 1));
  obj->front = 0;
  obj->rear = 0;
  obj->MaxSize = MaxSize;
  return obj;
}

3.判断满

判断为满:(rear+1) % (MaxSize+1) = front;

此时的MaxSize = 6;rear = 7; front = 0;

(6+1)%7=0 = 0;所以,满。

循环队列最后一个空间保证为空NULL;

//判断满
bool MCQueueIsFull(MCQueue* obj)
{
  return (obj->rear + 1) % (obj->MaxSize + 1) == obj->front;
}

4.判断空

此时满足条件front = rear;

//判断空 
bool MCQueueIsEmpty(MCQueue* obj)
{
  return obj->front == obj->rear;
}

5.入队

rear++在这种情况下将不能实现,需要取余求模

rear = (rear+1)%(MaxSize+1)

如图:

//入队
bool MCQueueIsIn(MCQueue* obj, int value)
{
  //判断是否为满 
  if (MCQueueIsFull(obj))
    return false;
  obj->rear = value;
  obj->rear = (obj->rear + 1) % (obj->MaxSize + 1);
  return true;
}

6.出队

出队列时面临的情况与入队时一样考虑。

//出队
bool MCQueueIsOut(MCQueue* obj)
{
  if (MCQueueIsEmpty(obj))
    return false;
  //删不删 front指向的元素无所谓 ,不影响
  obj->front = (obj->front+1)% (obj->MaxSize + 1);
  return true;
}

7.返回队列头元素

//返回队列头元素 
int ReturnFront(MCQueue* obj)
{
  //如果为空返回-1
  if (MCQueueIsEmpty(obj))
    return -1;
  return obj->a[obj->front];
}

8.返回队列尾元素

//返回队列尾元素
int ReturnRear(MCQueue* obj)
{
  //如果为空返回-1
  if (MCQueueIsEmpty(obj))
    return -1;
  int pos = (obj->rear + obj->MaxSize) % (obj->MaxSize + 1);
  return obj->a[pos];
}

9. 释放

//释放
void Free(MCQueue* obj)
{
  free(obj->a);
  free(obj);
}
相关文章
|
6月前
|
存储 Java 容器
深入浅出 栈和队列(附加循环队列、双端队列)
深入浅出 栈和队列(附加循环队列、双端队列)
|
6月前
|
存储
【数据结构】循环队列
【数据结构】循环队列
62 0
|
6月前
|
算法 调度 C++
【C/C++ 数据结构 线性表】C/C++中队列的原理与实现:从基础到循环队列
【C/C++ 数据结构 线性表】C/C++中队列的原理与实现:从基础到循环队列
153 0
数据结构第九弹---循环队列
数据结构第九弹---循环队列
|
存储 算法 编译器
【霍洛维兹数据结构】栈和队列 | 动态循环队列 | 迷宫问题 | 表达式 | 多重栈&多重队列
【霍洛维兹数据结构】栈和队列 | 动态循环队列 | 迷宫问题 | 表达式 | 多重栈&多重队列
88 0
|
5月前
|
存储 算法
【数据结构和算法】--队列的特殊结构-循环队列
【数据结构和算法】--队列的特殊结构-循环队列
34 0
|
1月前
|
存储
【初阶数据结构】深入解析循环队列:探索底层逻辑
【初阶数据结构】深入解析循环队列:探索底层逻辑
|
4月前
|
存储 索引
【数据结构OJ题】设计循环队列
力扣题目——设计循环队列
36 1
【数据结构OJ题】设计循环队列
|
3月前
|
算法
【数据结构与算法】循环队列
【数据结构与算法】循环队列
24 0
|
5月前
|
存储 算法 调度
【数据结构与算法】详解循环队列:基于数组实现高效存储与访问
【数据结构与算法】详解循环队列:基于数组实现高效存储与访问