【刷题】622. 设计循环队列

这篇具有很好参考价值的文章主要介绍了【刷题】622. 设计循环队列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


622. 设计循环队列

一、题目描述

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

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。

二、示例

MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1); // 返回 true
circularQueue.enQueue(2); // 返回 true
circularQueue.enQueue(3); // 返回 true
circularQueue.enQueue(4); // 返回 false,队列已满
circularQueue.Rear(); // 返回 3
circularQueue.isFull(); // 返回 true
circularQueue.deQueue(); // 返回 true
circularQueue.enQueue(4); // 返回 true
circularQueue.Rear(); // 返回 4

三、使用顺序表实现

使用顺序表实现的循环队列:

循环队列的结构定义:
1.首先顺序表的大小固定,从上面接口定义可以看到,顺序表能存储元素个数为队列的长度k,这可以通过malloc申请固定长度空间实现。
2.其次队列需要队头和队尾,需要front和rear两个索引。

队空条件:

front == rear

队满条件:

我们发现此时队满的条件也为 front == rear,这就无法区分是队空还是队满。

为此,我们可以采用以下两个解决方案:

1.预留一个空间用来区分队空和队满:

// 队空
front == rear
// 队满
rear + 1 == front

2.增加一个size变量记录队列中元素个数:

// 队空
size == 0
// 队满
size == k

这里我们采用第一种方式,采取牺牲一个存储空间的方法,来区分队空和队满。此时实现队列所用的顺序表的长度应该为 k+1。

同时采用第一种方法时,在计算队列中元素的个数时需要计算给出:

(rear + k + 1 - front) % (k + 1)

3.1 循环队列的结构定义

下面给出队列的结构定义:

typedef struct {
	int front;
	int rear;
	int k;
	int* a;
} MyCircularQueue;

3.2 循环队列初始化与销毁

初始化:
这里rear表示队尾元素下一个位置。

MyCircularQueue* myCircularQueueCreate(int k) {
	MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
	// 采用牺牲一个存储空间的方法区分队空和队满
	obj->a = (int*)malloc(sizeof(int) * (k + 1));
	obj->front = obj->rear = 0;
	obj->k = k;

	return obj;
}

销毁:

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

3.3 循环队列判空

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

3.4 循环队列判满

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

3.5 入队

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
	// 如果队满返回false
	if (myCircularQueueIsFull(obj))
		return false;

	// 入队就是顺序表尾插
	obj->a[obj->rear] = value;
	obj->rear++;
	obj->rear %= (obj->k + 1);

	return true;
}

3.6 出队

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
	// 队空不能出队
	if (myCircularQueueIsEmpty(obj))
		return false;

	// 出队就是顺序表头删 头指针加1即可
	obj->front++;
	obj->front %= (obj->k + 1);

	return true;
}

3.7 队首元素

int myCircularQueueFront(MyCircularQueue* obj) {
	// 返回队首元素保证队列不为空
	if (myCircularQueueIsEmpty(obj))
		return -1;

	return obj->a[obj->front];
}

3.8 队尾元素

从初始化可以看出rear指向队尾元素的下一个位置,所以rear应该先减1,才是在顺序表中的索引。又由于rear可能会为0,因此需要先加 k+1使rear指向表后,然后再减1使rear指向表中最后一个元素位置。可以写成:

rear + (k + 1- 1 = rear + k

再考虑到其余普通情况防止顺序表越界,还需要队该数取余:

(rear + k) % (k + 1)

便有以下返回队尾元素的代码:文章来源地址https://www.toymoban.com/news/detail-447923.html

int myCircularQueueRear(MyCircularQueue* obj) {
	// 返回队尾元素保证队列不为空
	if (myCircularQueueIsEmpty(obj))
		return -1;

	return obj->a[(obj->rear + obj->k) % (obj->k + 1)];
}

完整接口实现

typedef struct {
	int front;
	int rear;
	int k;
	int* a;
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
	MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
	// 采用牺牲一个存储空间的方法区分队空和队满
	obj->a = (int*)malloc(sizeof(int) * (k + 1));
	obj->front = obj->rear = 0;
	obj->k = k;

	return obj;
}

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

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

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
	// 如果队满返回false
	if (myCircularQueueIsFull(obj))
		return false;

	// 入队就是顺序表尾插
	obj->a[obj->rear] = value;
	obj->rear++;
	obj->rear %= (obj->k + 1);

	return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
	// 队空不能出队
	if (myCircularQueueIsEmpty(obj))
		return false;

	// 出队就是顺序表头删 头指针加1即可
	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;

	return obj->a[(obj->rear + obj->k) % (obj->k + 1)];
}



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

到了这里,关于【刷题】622. 设计循环队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 力扣622:设计循环队列(中等)

    目录 思考 一,循环队列的初始化myCircularQueueCreate 二,判断是否为空myCircularQueueIsEmpty 三,判断队列是否满了bool myCircularQueueIsFull 四,队列的插入myCircularQueueEnQueue 五,队列的删除myCircularQueueDeQueue 六,队列取头元素和尾元素myCircularQueueFront   //   myCircularQueueRear 七,销毁队列

    2024年03月13日
    浏览(39)
  • 数据结构:循环队列的实现(leetcode622.设计循环队列)

      目录 一.循环队列简单介绍 二.用静态数组实现循环队列 1.数组循环队列结构设计 2.数组循环队列的堆区内存申请接口  3.数据出队和入队的接口实现 4.其他操作接口 5.数组循环队列的实现代码总览  三.静态单向循环链表实现循环队列  1.链表循环队列的结构设计 2.创建静态

    2024年02月03日
    浏览(45)
  • 数据结构刷题训练:设计循环队列(力扣OJ)

    目录 文章目录 前言 1. 题目:设计循环队列 2. 思路 3. 分析  3.1 定义循环队列  3.2 创建队列  3.3 判空和判满  3.4 入队  3.5 出队  3.6 取队头队尾数据  3.7 销毁队列  4. 题解 总结         当谈到队列数据结构时,很多人可能会想到普通的队列,即先进先出(FIFO)的数据结

    2024年02月13日
    浏览(47)
  • 什么?要求设计一个循环队列?

    🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯C语言初阶 🍔🍟🌯C语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介::讲解用c语言实现数据结构的循环队列. 先声明一下: 题目来源:力扣(LeetCode) 题目名称: 设计循环队列 :题目链接 难度: 中等 介绍: 设计你的

    2024年02月07日
    浏览(37)
  • leetcode——设计循环队列

    设计循环队列 这个题目在这里小编只分享一个解题思路,因为还有一个思路小编还在尝试,一直过不了,还在这里不断尝试,等我试出来的时候我在分享给大家,首先我们在这里给出的是数组的形式,后面在分享单链表的思路,因为数组在内存上是连续的,这里给出的思路是

    2024年02月05日
    浏览(39)
  • 力扣设计循环队列

    目录 1.使用了数组来表达循环 2.循环队列是否为空 3.循环队列是否已满。 4.初始化 5.向循环队列插入一个元素。如果成功插入则返回真                          6.从队首获取元素。如果队列为空,返回 -1                                  7.获取队尾元素。如果队列为

    2024年02月07日
    浏览(35)
  • 栈和队列(二) 队列的实现,用栈实现队列,用队列实现栈,设计循环队列

    这里的队列我们使用链式队列,好处就是可以很方便的取出队头的元素。 使用顺序队列取出队头元素所花费的时间复杂度为O(N),把后面的元素向前移动一个下标所花费的时间。 链式队列的存储结构: 接口函数的实现 ` leetcode做题链接 主要思想:用两个队列来实现一个栈

    2024年02月11日
    浏览(39)
  • 数据结构OJ:设计循环队列

    本题为LeetCode上的经典题目,题目要求我们设计一种循环队列,满足FIFO原则且队尾被连接在队首之后。 题目中介绍循环队列的好处是可以重复利用空间,所以我们很容易想到在初始化时即开辟指定大小的空间,之后便不需要再开辟空间,只需后续销毁即可。 首先我们要选择

    2024年04月17日
    浏览(66)
  • 【数据结构与算法】设计循环队列

      🧑‍🎓 个人主页:简 料   🏆 所属专栏:C++   🏆 个人社区:越努力越幸运社区   🏆 简       介: 简料简料,简单有料~在校大学生一枚,专注C/C++/GO的干货分享,立志成为您的好帮手 ~ C/C++学习路线 (点击解锁) ❤️ C语言阶段(已结束) ❤️ 数据结构与算法(ing) ❤

    2024年01月17日
    浏览(45)
  • 【数据结构与算法】用队列实现栈&&用栈实现队列&&设计循环队列

    🌠 作者:@ 阿亮joy. 🎆 专栏:《数据结构与算法要啸着学》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、

    2024年01月20日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包