设计循环队列,解决假溢出问题

什么是假溢出?

当我们使用队列这种基本的数据结构时,很容易发现,随着入队和出队操作的不断进行,队列的数据区域不断地偏向队尾方向移动。当我们的队尾指针指向了队列之外的区域时,我们就不能再进行入队操作了,而此时由于队头已经偏离原来位置,也就意味着实际上队列并没有满。这种实际上还有空间,但是却发生了溢出的现象就称为假溢出现象。

假设有以下队列,初始元素为1、2、3、4、5,队头元素是1,队尾元素是5.

当我们弹出队头元素两次得到队列:

这个时候top指针向右边偏移,如果再进行入队操作我们会发现rear指针已经不能向后移动了,而此时队列并没有满(top前面还有空间)。

这就是假溢出。

如何解决假溢出问题?

为了避免假溢出问题,我们需要对队列进行优化--循环队列。

对于前面的问题,我们发现导致假溢出的主要问题就是尾指针rear不能指向可以存放空间的地址,换句话来说就是不能指向前面已经出队了元素的地址。针对这一问题,我们整个队列看成一个可以循环的环状结构,指向队头队尾的指针往后走还能回到原来的位置。

 这样一来,前面已经出队元素的空间我们依旧可以存放元素,也就解决了假溢出的问题。(这里rear指向队尾元素的下一个元素)。

模拟循环队列

首先假设我们队列的最大存储数据个数为k。

用一个数组来模拟循环队列,并且初始化容量为k+1,队头队尾指针都指向下标为0的元素地址

为什么容量要多一个呢?

为了更好的区分队列为空和队列已满。


 

如何判断循环队列是否为空?

if(top==rear)为真则队列为空

如何判断循环队列是否为满?

由于我们多开辟了一个元素的空间,且这个空间不存放元素,也就意味着,如果已经存了k个元素,此时的rear指向这个空的区域,rear指向空间的下一个空间的元素被top指针指向

if((rear+1)%(k+1)==top)//真则队列为满

如何求得循环队列的元素个数?

num=(rear+k-top)%(k+1)//num为循环队列元素个数

由于rear指针可能在top指针的前面,所以我们不能直接使用rear-top.

那么我们可以这么想,之所以rear会出现在top前面,是因为rear已经走了一圈了(假设只多走了一圈),那么rear移动的总距离就是当前元素位置加队列长度,top移动的距离就是当前下标。

力扣面试题:

622. 设计循环队列icon-default.png?t=N7T8https://leetcode.cn/problems/design-circular-queue/

代码:

typedef struct {int *val;int front;int back;int k;int size;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue *obj=(MyCircularQueue *)malloc(sizeof(MyCircularQueue));obj->val=(int*)malloc(sizeof(int)*(k+1));obj->front=0;obj->back=0;obj->k=k;obj->size=0;return obj;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return ((obj->back)==(obj->front));
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return (((obj->back+1)%(obj->k+1))==obj->front);
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj))return false;obj->val[obj->back]=value;obj->back=(obj->back+1)%(obj->k+1);return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return false;obj->front=(obj->front+1)%(obj->k+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;return obj->val[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;int k=obj->k;return obj->val[(obj->back+k)%(k+1)];
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->val);obj->val=NULL;free(obj);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/208070.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go 语言函数、参数和返回值详解

函数是一组语句,可以在程序中重复使用。函数不会在页面加载时自动执行。函数将通过调用函数来执行。 创建函数 要创建(通常称为声明)一个函数,请执行以下操作: 使用 func 关键字。指定函数的名称,后跟括…

打不开clickonce问题解决过程

1.用户电脑user文件夹下有xx和xx.1两个账户,原先安装在xx账户下,后修了电脑原数据保留在xx.1,新创建XX,之后clickonce就打不开了表现为没有反应,,删除注册表和appdata都只能正常安装,但是不能打开,没有任何报错,发现在我的电脑下打开有这样的提示,,在用户电脑上没有 尝试通过修…

电大搜题——让学习变得轻松高效

作为一名现代学者,您一定时刻关注着教育领域的进展和创新。今天,我将向大家介绍一个名为“电大搜题”的神奇工具,它将为您的学习之路带来一场完美的革命。 在快节奏的现代社会中,学习已经成为每个人追求成功的必经之路。然而&…

攻防世界-web-Confusion1

1. 题目描述 打开链接,如图 点击Login和Rigister,都报错 但是有提示 指出了flag所在的位置,题目中直接能获取到的信息暂时就这么些了 2. 思路分析 既然告诉了我们flag文件的位置,那么要读取到这个文件,要么是任意文…

设计模式-创建型模式-工厂方法模式

一、什么是工厂方法模式 工厂模式又称工厂方法模式,是一种创建型设计模式,其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。工厂方法模式是目标是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。…

双流网络论文精读笔记

精读视频:双流网络论文逐段精读【论文精读】_哔哩哔哩_bilibili Two-Stream Convolutional Networks for Action Recognition in Videos 传统的神经网络难以学习到物体的运动信息,双流网络则通过光流将物体运动信息抽取出来再传递给神经网络 给模型提供…

未来制造业的新引擎:工业机器人控制解决方案

制造业正经历着一场革命性的变革 在这个变革的浪潮中,工业机器人成为推动制造业高效生产的关键力量。然而,要发挥机器人的最大潜力,一个强大而智能的控制系统是必不可少的。在这个领域,新一代的工业机器人控制解决方案正崭露头角&…

Gradle常用命令与参数依赖管理和版本决议

一、Gradle 常用命令与参数 本课程全程基于 Gradle8.0 环境 1、Gradle 命令 介绍 gradle 命令之前我们先来了解下 gradle 命令怎么在项目中执行。 1.1、gradlew gradlew 即 Gradle Wrapper,在学习小组的第一课时已经介绍过了这里就不多赘述。提一下执行命令&am…

python解决登录图形验证码

摘要:测试过程中经常遇到图片验证码,以下主要是调用百度OCR图片识别获取验证码,实现登录 1、百度云申请创建应用

Autoware.universe部署06:使用DBC文件进行UDP的CAN通信代码编写

目录标题 一、安装DBC文件编辑工具VectorCANdb二、编写DBC文件2.1 CAN通信协议2.2 编写DBC文件2.2.1 根据CAN协议设置signals2.2.2 设置报文2.2.3 建立节点 三、根据DBC文件编写ROS2驱动程序四、实际通信调试 根据CAN协议编写DBC文件,通过DBC文件编写ROS2包进行UDP通…

【前端】前端监控⊆埋点

文章目录 前端监控分为三个方面前端监控流程异常监控常见的错误捕获方法主要是 try / catch 、window.onerror 和window.addEventListener 等。Promise 错误Vue 错误React 错误 性能监控用户行为监控常见的埋点方案来源 前端监控分为三个方面 异常监控(监控前端页面…

2014年6月18日 Go生态洞察:Go 1.3 版本发布

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…