当前位置: 首页 > news >正文

(力扣)循环队列的实现与详解(C语言)

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

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

 如图所示,可以形象的理解为这样的队列。

但我们在实现循环队列的时候,可以用数组实现,也可以用链表来实现,那我们接下来就先试试怎么用数组来实现这个循环队列。

 此时我们设计了一个数组,并且预先规定数组的大小。这时候,我们把数组的大小定义为4。这也是我们必须要做的。当是空队列的时候,队列头和队列尾都在同一个位置,比如都在数组的0位置。下图使我们插入一个数据看看。

 当我们在rear的位置插入1的时候,rear++了,同样的,加更多的数据也是一样的。

 但如果我们再往后插入数据,那我们怎么办呢,是不是满了,rear的下标怎么到front的位置呢。

 从这个图中我们可以看出,当rear和front相等时,他们好像是满了,我们能不能以这个条件来判断它是不是满了呢?我们先思考下,后面我们在说,接下来我们再来看下,怎么从rear=3,突然就到0了,那我们是不是可以想到%这个操作数,(rear+1)%k;k为我们的数组的大小。

现在我们解决了这个问题,但能不能用front和rear相等来判断数组满了呢?接下来在画一个图,看看行不行。

 这样好像不太行,好像空的也就是这样

那我们怎么做呢?现在有一个办法,就是我们比要存的数据多开一个空间。如图:

 如果我们在rear的下一个结点与Front相等,那就是满了,所以,我们接下来就来上程序:

typedef struct   //建一个结构体
{
	int*a;//数据存放到这数组里
	int k;//存放数据的大小
	int front;
	int rear;
} MyCircularQueue;

bool myCircularQueueIsEmpty(MyCircularQueue* obj);//判断队列是不是为空
bool myCircularQueueIsFull(MyCircularQueue* obj);//判断队列是不是为满
MyCircularQueue* myCircularQueueCreate(int k)//创建结构,并初始化
{
	MyCircularQueue*q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
	q->a = (int*)malloc(sizeof(int)*(k + 1));
	q->front = q->rear = 0;
	q->k = k;
	return q;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
	if (myCircularQueueIsFull(obj))
	{
		return false;
	}
	obj->a[obj->rear] = value;
	++obj->rear;
	obj->rear %= (obj->k + 1);//判断如果不%的话是不是会数组的长度,如果超出了,%下让它回到0的位置
	return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
	if (myCircularQueueIsEmpty(obj))
	{
		return false;
	}
	++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;
	}
	//int i=(obj->rear+obj->k)%(obj->k+1);
	//return obj->a[i];
	if (obj->rear == 0)
	{
		return obj->a[obj->k];
	}
	else
	{
		return obj->a[obj->rear - 1];
	}
}

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

bool myCircularQueueIsFull(MyCircularQueue* obj)
{

	return (obj->rear + 1) % (obj->k + 1) == obj->front;//同样的,防止加1后,不能回到起始位置
}

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

相关文章:

  • 判断单值二叉树的详解与实现(c语言)
  • 求链式二叉树第K层的结点数
  • 排序之插入排序(图解)
  • 排序之希尔排序(图解)
  • 排序之选择排序(图解)
  • C++之默认参数详解
  • 力扣(两数相加)C语言
  • 力扣(反转二叉树)C语言
  • 力扣-平衡二叉树(C语言)
  • 力扣—对称二叉树(C语言)
  • 牛客网—二叉树遍历(C语言)
  • C++之引用详解
  • c++之模板初阶
  • C++之string源代码详解
  • 电话号码组合(力扣)
  • 收藏网友的 源程序下载网
  • canvas绘制圆角头像
  • Fabric架构演变之路
  • Iterator 和 for...of 循环
  • javascript 哈希表
  • mysql常用命令汇总
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Vue UI框架库开发介绍
  • 安装python包到指定虚拟环境
  • 初识MongoDB分片
  • 记一次和乔布斯合作最难忘的经历
  • 前端_面试
  • 前端临床手札——文件上传
  • 时间复杂度与空间复杂度分析
  • 实现简单的正则表达式引擎
  • 微信公众号开发小记——5.python微信红包
  • 我从编程教室毕业
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • ​业务双活的数据切换思路设计(下)
  • #Java第九次作业--输入输出流和文件操作
  • (3)nginx 配置(nginx.conf)
  • (52)只出现一次的数字III
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (第61天)多租户架构(CDB/PDB)
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)EOS中账户、钱包和密钥的关系
  • (转)JAVA中的堆栈
  • (转)程序员技术练级攻略
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • ****Linux下Mysql的安装和配置
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .NET应用架构设计:原则、模式与实践 目录预览