一、环形队列的优势

环形队列是一种特殊的队列,它可以解决普通队列在使用时空间利用不充分的问题。在环形队列中,当队列满时,队列的尾指针指向队列的起始位置,而不是指向队列的最后一个元素。这样可以在不浪费空间的情况下存储更多的元素。
下面我们来详细讲解一下环形队列的实现。

二、环形队列的定义

首先,我们需要定义一个环形队列的结构体,包含以下成员变量:

  • int *queue:指向环形队列的指针;
  • int front:指向队列的头部;
  • int rear:指向队列的尾部;
  • int size:队列的容量。
typedef struct {
int *queue;
int front;
int rear;
int size;
} MyCircularQueue;

三、环形队列的初始化

在初始化环形队列时,我们需要为其动态分配内存空间,并将头指针和尾指针都初始化为-1,表示队列为空。

MyCircularQueue* myCircularQueueCreate(int k)
{
MyCircularQueue *obj =(MyCircularQueue*)malloc(sizeof(MyCircularQueue));

obj->queue = (int *)malloc(sizeof(int) * k);
obj->front = -1;
obj->rear = -1;
obj->size = k; return obj;
}

四、环形队列的入队

当向队列中插入元素时,我们需要先判断队列是否已满。如果队列已满,则插入失败,返回false;否则,将元素插入到队列的尾部,并将尾指针指向下一个位置。

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
if (myCircularQueueIsFull(obj))
{
return false;
} obj->rear = (obj->rear + 1) % obj->size;
obj->queue[obj->rear] = value;
if (obj->front == -1)
  {
obj->front = obj->rear;
} return true;
}

五、环形队列的出队

当从队列中删除元素时,我们需要先判断队列是否为空。如果队列为空,则删除失败,返回false;否则,将元素从队列的头部删除,并将头指针指向下一个位置。

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

六、环形队列的查看队首元素

当查看队列的头部元素时,我们需要先判断队列是否为空。如果队列为空,则返回-1;否则返回队列头部的元素。

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

七、环形队列的查看队尾元素

当查看队列的尾部元素时,我们需要先判断队列是否为空。如果队列为空,则返回-1;否则,返回队列尾部的元素。

int myCircularQueueRear(MyCircularQueue* obj)
{
if (myCircularQueueIsEmpty(obj))
{
return -1;
} return obj->queue[obj->rear];
}

八、环形队列的判断是否为空

当判断队列是否为空时,只需要判断头指针是否为-1即可。

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

九、环形队列的判断是否已满

当判断队列是否已满时,只需要判断尾指针下一个位置是否为头指针即可。

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

十、环形队列的销毁

当环形队列不再使用时,需要释放其占用的内存空间。

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

总的来说,环形队列是一种非常实用的数据结构,特别适用于空间有限的情况下。通过合理的设计和实现,可以使得队列的空间利用率更高,并且操作效率也比较高。


关于更多嵌入式C语言、FreeRTOS、RT-Thread、Linux应用编程、linux驱动等相关知识,关注公众号【嵌入式Linux知识共享】,后续精彩内容及时收看了解。

C语言之环形队列的更多相关文章

  1. <2014 05 16> 线性表、栈与队列——一个环形队列的C语言实现

    栈与队列都是具有特殊存取方式的线性表,栈属于先进后出(FILO),而队列则是先进先出(FIFO).栈能够将递归问题转化为非递归问题,这是它的一个重要特性.除了FILO.FIFO这样的最普遍存取方式外, ...

  2. 【数据结构】C++语言无锁环形队列的实现

    无锁环形队列 1.Ring_Queue在payload前加入一个头,来表示当前节点的状态 2.当前节点的状态包括可以读.可以写.正在读.正在写 3.当读完成后将节点状态改为可以写,当写完成后将节点状态 ...

  3. 【数据结构】C++语言环形队列的实现

    队列--先进先出 队列的一个缺点--出队后的内存空间浪费了,不能二次利用 环形队列--解决以上缺点的队列,用过的内存空间可以重复利用 github: https://github.com/HITFis ...

  4. C#实现环形队列

    概述 看了一个数据结构的教程,是用C++写的,可自己C#还是一个菜鸟,更别说C++了,但还是大胆尝试用C#将其中的环形队列的实现写出来,先上代码: public class MyQueue<T& ...

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

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

  6. 【转】C#环形队列

    概述 看了一个数据结构的教程,是用C++写的,可自己C#还是一个菜鸟,更别说C++了,但还是大胆尝试用C#将其中的环形队列的实现写出来,先上代码: 1 public class MyQueue< ...

  7. Atitit.提升软件稳定性---基于数据库实现的持久化 循环队列 环形队列

    Atitit.提升软件稳定性---基于数据库实现的持久化  循环队列 环形队列 1. 前言::选型(马) 1 2. 实现java.util.queue接口 1 3. 当前指针的2个实现方式 1 1.1 ...

  8. 队列(Queue)--环形队列、优先队列和双向队列

    1. 队列概述 队列和堆栈都是有序列表,属于抽象型数据类型(ADT),所有加入和删除的动作都发生在不同的两端,并符合First In, First Out(先进先出)的特性. 特性: ·FIFO ·拥 ...

  9. 环形队列C++实现

    大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang 以下鄙人用C++实现了环形队列 /******************************** ...

  10. C语言实现,队列可伸缩

    两个栈实现一个队列,C语言实现,队列可伸缩,容纳任意数目的元素. 一.思路:1.创建两个空栈A和B:2.A栈作为队列的入口,B栈作为队列的出口:3.入队列操作:即是入栈A:4.出队列操作:若栈B为空, ...

随机推荐

  1. GPU Skinning

    这个工具的作用是同一种角色在同屏里面出现一大堆时,可以大幅度的降低DrawCall.我试了一下,感觉挺有意思的,各位可以试试.它的原理实际上是把骨骼矩阵存在配置文件里面,然后通过特殊的shader,计 ...

  2. Nodejs 发送 TCP 消息的正确姿势

    最近使用 NODE-RED 跟 TCP 打交道.NODE-RED 里内建了一个节点叫"tcp-out",看文档呢使用这个节点可以很方便的把 payload 用 TCP 协议发送出去 ...

  3. springboot多环境开发兼容问题(Maven和boot)

    <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven ...

  4. ABAP 屏幕开发-仿采购订单

    1.功能说明 本文档通过一个简单的实例,仿照采购订单的界面,介绍屏幕开发. 2.效果展示 3.功能实现 3.1界面框架 从界面上看,整个界面框架分为四部分.抬头行,抬头页签,行项目,项目细节.其中抬头 ...

  5. vue双向监听proxy

    console.log('判断页面是否有滚动条', this.hasScrollbar) const that = this that.count = 0 // 计数 that.scrollProxy ...

  6. 剑指 offer 第 24 天

    第 24 天 数学(中等) 剑指 Offer 14- I. 剪绳子 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[ ...

  7. QML 界面切换的几种方法(带示例代码)

    QML 界面切换的几种方法(带示例代码)

  8. 地图:leaflet基本使用

    leaflet:一个开源并且对移动端友好的交互式地图 JavaScript 库 中文文档:https://leafletjs.cn/reference.html 官网(英文):https://icli ...

  9. ICMP隐蔽隧道攻击分析与检测(四)

    • ICMP隧道攻击通讯特征和特征提取 一.ICMP Ping正常通讯特征总结 一个正常的 ping 每秒最多只会发送两个数据包,而使用 ICMP隧道的服务器在同一时间会产生大量 ICMP 数据包 正 ...

  10. 使用HTMLform表单操作腾讯云DNS控制台

    在使用中经常需要修改DNS记录,或者查询.删除操作.每次都得登录腾讯云控制台,腾讯云比较鸡肋的一点就是需要进行微信扫码登录,每次操作太不方便. 可以使用api接口进行操作腾讯云上的产品.所以使用HTM ...