设计循环队列(LeetCode:622.设计循环队列)
目录
写在前面的话:
一,题目分析
二,各接口实现
2.1构造循环队列
2.1.1两种不同形式的队列
2.1.2顺序表实现循环队列
2.2向队列中插入元素
2.3删除队列中元素
2.4获取队尾和队首元素
2.4.1获取队尾元素
2.4.2获取队首元素
2.4.3代码实现
2.5判空判满接口
2.5.1两种做法实现
2.5.2正确做法
2.5.3代码实现
2.6释放队列
源码实现
写在前面的话:
小伙伴大家好啊!今天小编为大家带来一篇有关循环队列的题目。虽然说对于该题目,我们是将队列的接口直接拿过来用的,但是这个题目仍旧有一定的难度。
一,题目分析
如下图题目所示,循环队列首先基于先进先出,然后队尾连接在队首形成一个循环队列。它的优势表现在,如果队列链表满了之后,我们可以直接覆盖继续增加元素。
二,各接口实现
如下图所示,题目中要求有这些接口:
那么接下来,我们挨个实现。
2.1构造循环队列
2.1.1两种不同形式的队列
首先我们需要构造出一个空的循环队列。这里我们采用顺序表实现,当然也可以用链表实现,如下图所示:
题目中要求,我们需要设置一个队列长度为 k 的一个循环队列。接下来我们的例子都以 k 为 4 来解题。
那么我们发现,队列长度是 4 ,但是我们开辟了 5 个空间,这是因为如果后面在判断队列的空和满时,必须这样做,才能判断,否则将没法判断。那么这里我们暂时不关心这个,在后面我们会解释。
2.1.2顺序表实现循环队列
这里我们通过顺序表实现。首先,我们需要两个指针,一个 front 表示头,一个 tail 表示尾。一个数组 a,以及一个 k 表示当前队列的长度 。
typedef struct {//数组实现int front;int tail;int k;int *a;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue*cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));cq->front=0;cq->tail=0;cq->k=k;cq->a =(int*)malloc(sizeof(int)*(k+1));return cq;
}
那么我们在构造队列时,需要注意的就是需要开辟 K+1 个空间,最后一个不能忘记的是将新开辟的空间返回。
2.2向队列中插入元素
首先,我们需要判断当前队列是否为满,如果当前队列为满的话,则直接返回false,否则进行插入操作。
如下代码所示,当队列不为空,然后进行插入操作时。首先我们将该元素插入尾指针 tail 表示的数组 a ,然后将尾指针自增 1 ,最后需要对 k 的值进行取模操作,因为这里表示的是循环队列,我们需要将其限制在一定的范围内。
而这里的取模也非常简单,就是将 tail 对 k+1 进行取模,但是需要注意这里只有 obj->k ,没有单独的 k 。
2.3删除队列中元素
对于顺序表实现的队列来说,删除元素是比较简单的,但是我们需要删除的是队头的元素,因为队列的特性就是“先进先出”。所以这里我们判断完队列中不为空的时候,只需要将 front 自增 1即可,这也是我们数组中一般进行删除的方式。
当然 一定不能忘记的是对其取余,保证 front 限制在 队列长度的范围内。
2.4获取队尾和队首元素
那么对于获取队尾和队首元素,相对来说是比较简单的。但是这里需要注意的是,两个指针 front 和 tail 在每次删除或者插入元素之后,会自增。
以及题目中要求的。如果获取不到,则直接返回 -1。
2.4.1获取队尾元素
如下图所示,当前队尾元素是 tail 指针的前一个元素,所以这里我们需要对 tail 做一个修正之后才能得到队尾元素:(tail+k)%(k+1)
2.4.2获取队首元素
那么对于获取队首元素是相对比较简单的。直接返回当前 front 所在的元素即可。
2.4.3代码实现
两个接口的代码实现如下所示:
int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;return obj->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;//因为tail总是指向最后一个元素后面的空位置//所以需要找tail之前的那个位置上的元素int i=(obj->tail+obj->k)%(obj->k+1);return obj->a[i];
}
2.5判空判满接口
2.5.1两种做法实现
如下图,我们可以看出,之前我们多开辟一个空间的作用就有了,如果我们没有多开辟一个空间,那么最开始没有数据的时候,以及数据满的时候,front 和 tail 指向的是同一个地方。
这样的表示方法,我们怎样去判断当前队列是否为空或者满呢?没法判断的,所以我们需要多开辟一个空间。
2.5.2正确做法
2.5.3代码实现
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->front == obj->tail;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->tail+1) % (obj->k+1) == obj->front;
}
2.6释放队列
开辟的两个指针,都需要释放哦!
源码实现
typedef struct {//数组实现int front;int tail;int k;int *a;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue*cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));cq->front=0;cq->tail=0;cq->k=k;cq->a =(int*)malloc(sizeof(int)*(k+1));return cq;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//如果为满,返回falseif(myCircularQueueIsFull(obj))return false;//否则,添加元素,然后tail后移一位,如果超出数组范围,进行取模obj->a[obj->tail]=value;obj->tail++;obj->tail %= (obj->k+1);return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return false;//有元素,删除//删除数组元素,不用free,只需要将其覆盖obj->front++;obj->front%=(obj->k+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;return obj->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;//因为tail总是指向最后一个元素后面的空位置//所以需要找tail之前的那个位置上的元素int i=(obj->tail+obj->k)%(obj->k+1);return obj->a[i];
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->front == obj->tail;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->tail+1) % (obj->k+1) == obj->front;
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}
好的,那么对于循环队列的题目就结束啦,如果小伙伴们有问题,可以留言评论哦!
设计循环队列(LeetCode:622.设计循环队列)相关推荐
- leetcode 622——设计循环队列
leetcode 622--设计循环队列(C语言提交) 题目链接:leetcode 622--设计循环队列 题目描述: 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先 ...
- Leetcode 622. 设计循环队列
Leetcode 622. 设计循环队列学习 分析 代码 参考链接 分析 循环队列,自己做题时没考虑怎么实现,可以通过索引下标除以数组的长度实现循环.循环队列的队首元素和队尾元素是动态变化的,删除一个 ...
- c++数据结构中 顺序队列的队首队尾_yiduobo的每日leetcode 622.设计循环队列
祖传的手艺不想丢了,所以按顺序写一个leetcode的题解.计划每日两题,争取不卡题吧. 622.设计循环队列https://leetcode-cn.com/problems/design-circu ...
- Java实现 LeetCode 622 设计循环队列(暴力大法)
622. 设计循环队列 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器" ...
- 【Java】 LeetCode 622. 设计循环队列 (有关实现循环队列的讲解)
题目: 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器". 循环队列的一 ...
- Leetcode 622. 设计循环队列 解题思路及C++实现
解题思路: 使用整数数组来作为队列的数据结构,设置两个位置指针:front 和 end,front指向队首元素,end指向队尾的下一个元素(即为空位置).当 front 和 end 相等时,有两种情况 ...
- LeetCode 641. 设计循环双端队列
文章目录 1. 题目信息 2. 解题 1. 题目信息 设计实现双端队列. 你的实现需要支持以下操作: MyCircularDeque(k):构造函数,双端队列的大小为k. insertFront(): ...
- leetcode 622. Design Circular Queue | 641. 设计循环双端队列(Java)
题目 https://leetcode.com/problems/design-circular-deque/ 题解 相关问题:leetcode 622. Design Circular Queue ...
- 【LeetCode 622 链表专项】设计循环队列
文章目录 1. 题目 1.1 示例 1.2 说明 1.3 限制 2. 解法一(基于数组) 2.1 分析 2.2 解答 2.3 复杂度 2.4 代码优化 3. 解法二(基于链表) 3.1 分析 3.2 ...
- 622. 设计循环队列(C实现)
题目 题目链接:622. 设计循环队列 思路 设计循环队列有两种实现方式 第一种是使用数组实现: 第二种是使用单链表实现: 而设计循环队列不管是使用数组实现还是使用单链表实现,都需要给数组预留出一个空 ...
最新文章
- 红旗linux可以做服务器吗,在红旗Linux中的E-MAIL服务器(postfix及dovecot)配置过程...
- Python-Django配置阿里大于的短信验证码接口
- python 中的下划线
- 图像处理之添加高斯与泊松噪声
- 如何应对数据库CPU打满?最优解在这里...
- C#刷遍Leetcode面试题系列连载(2): No.38 - 报数
- mfc try catch 捕获并显示_你的异常捕获够优雅不?求你别只会try{...} catch{...}了
- 59 MM配置-后勤发票校验-维护税代码缺省值
- php读取oracle,php读取oracle中数据库文件
- Python 操作 protobuf 常见用法
- 机器学习——模型融合
- linux 迅雷 命令行,Linux小迅雷:uGet下载工具加速 | 薄荷开源网
- [工作必备]pandas数据分析处理52个常用技巧
- Python 解析 spec 文件
- IntelliJ Save Action
- 初中生用计算机作弊,初中生,总是偷偷用手机作弊,好想哭怎么办?
- 最新超详细VMware虚拟机下载与安装(一篇足以带你上高速,附钥)
- 2021安居育才中学高考成绩查询,育才中学2017高考成绩
- Oracle查询语句及实例
- Linux脚本的制作命令