目录

写在前面的话:

一,题目分析

二,各接口实现

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.设计循环队列)相关推荐

  1. leetcode 622——设计循环队列

    leetcode 622--设计循环队列(C语言提交) 题目链接:leetcode 622--设计循环队列 题目描述: 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先 ...

  2. Leetcode 622. 设计循环队列

    Leetcode 622. 设计循环队列学习 分析 代码 参考链接 分析 循环队列,自己做题时没考虑怎么实现,可以通过索引下标除以数组的长度实现循环.循环队列的队首元素和队尾元素是动态变化的,删除一个 ...

  3. c++数据结构中 顺序队列的队首队尾_yiduobo的每日leetcode 622.设计循环队列

    祖传的手艺不想丢了,所以按顺序写一个leetcode的题解.计划每日两题,争取不卡题吧. 622.设计循环队列https://leetcode-cn.com/problems/design-circu ...

  4. Java实现 LeetCode 622 设计循环队列(暴力大法)

    622. 设计循环队列 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器" ...

  5. 【Java】 LeetCode 622. 设计循环队列 (有关实现循环队列的讲解)

    题目: 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器". 循环队列的一 ...

  6. Leetcode 622. 设计循环队列 解题思路及C++实现

    解题思路: 使用整数数组来作为队列的数据结构,设置两个位置指针:front 和 end,front指向队首元素,end指向队尾的下一个元素(即为空位置).当 front 和 end 相等时,有两种情况 ...

  7. LeetCode 641. 设计循环双端队列

    文章目录 1. 题目信息 2. 解题 1. 题目信息 设计实现双端队列. 你的实现需要支持以下操作: MyCircularDeque(k):构造函数,双端队列的大小为k. insertFront(): ...

  8. leetcode 622. Design Circular Queue | 641. 设计循环双端队列(Java)

    题目 https://leetcode.com/problems/design-circular-deque/ 题解 相关问题:leetcode 622. Design Circular Queue ...

  9. 【LeetCode 622 链表专项】设计循环队列

    文章目录 1. 题目 1.1 示例 1.2 说明 1.3 限制 2. 解法一(基于数组) 2.1 分析 2.2 解答 2.3 复杂度 2.4 代码优化 3. 解法二(基于链表) 3.1 分析 3.2 ...

  10. 622. 设计循环队列(C实现)

    题目 题目链接:622. 设计循环队列 思路 设计循环队列有两种实现方式 第一种是使用数组实现: 第二种是使用单链表实现: 而设计循环队列不管是使用数组实现还是使用单链表实现,都需要给数组预留出一个空 ...

最新文章

  1. 红旗linux可以做服务器吗,在红旗Linux中的E-MAIL服务器(postfix及dovecot)配置过程...
  2. Python-Django配置阿里大于的短信验证码接口
  3. python 中的下划线
  4. 图像处理之添加高斯与泊松噪声
  5. 如何应对数据库CPU打满?最优解在这里...
  6. C#刷遍Leetcode面试题系列连载(2): No.38 - 报数
  7. mfc try catch 捕获并显示_你的异常捕获够优雅不?求你别只会try{...} catch{...}了
  8. 59 MM配置-后勤发票校验-维护税代码缺省值
  9. php读取oracle,php读取oracle中数据库文件
  10. Python 操作 protobuf 常见用法
  11. 机器学习——模型融合
  12. linux 迅雷 命令行,Linux小迅雷:uGet下载工具加速 | 薄荷开源网
  13. [工作必备]pandas数据分析处理52个常用技巧
  14. Python 解析 spec 文件
  15. IntelliJ Save Action
  16. 初中生用计算机作弊,初中生,总是偷偷用手机作弊,好想哭怎么办?
  17. 最新超详细VMware虚拟机下载与安装(一篇足以带你上高速,附钥)
  18. 2021安居育才中学高考成绩查询,育才中学2017高考成绩
  19. Oracle查询语句及实例
  20. Linux脚本的制作命令

热门文章

  1. 【matlab】计算根据圆面积使用三角形来模拟产生的误差
  2. .isEmpty()使用示例
  3. 软件构造—ADT的理解
  4. 12 BST第K⼩的元素
  5. 求参数x 和y的平方和
  6. 跟女朋友交往一个月有感
  7. Android 禁止输入emoji表情符号
  8. 路由器工作模式 history和hash 以及重定向问题
  9. 比较好的宽屏分辨率 2048
  10. 上投摩根灵魂人物吕俊辞职