LeetCode622.设计循环队列

news/2024/10/30 15:27:59/

设计循环队列

  • 1.题目描述
  • 2.思路
  • 3.代码实现以及分析
    • 3.1 创建结构体
    • 3.2创建一个具体的循环队列
    • 3.3判断是否为空 和 判断是否为满
  • 4. 进队列 和 出队列
  • 5.取队首和队尾元素
  • 6.释放空间
  • 7.总结

1.题目描述


设计循环队列
在这里插入图片描述

2.思路

环形队列的抽象图

在这里插入图片描述

我们这里使用数组模拟实现循环队列,但是我们知道数组在实际当中并不是如上图这样的,我们要达成上图这样的效果可以多多利用 % 计算。

比如 任意一个数 % 5,得到的结果只能在 0 ~ 4 之间,所以我们可以利用这一性质,来完成我们的数组模拟实现循环队列。

3.代码实现以及分析

我们根据题目给的接口来一个个分析并实现

3.1 创建结构体

typedef struct {int* a;//a是数组int front;//队列头int rear;//队列尾int k;//k是数组有效空间,为什么说是有效空间?下面会解释
} MyCircularQueue;

3.2创建一个具体的循环队列

MyCircularQueue* myCircularQueueCreate(int k) {//k是队列的有效空间
//创建一个具体的结构MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//给我们的数组开辟 k + 1个空间,k + 1就是实际的空间,这个空间不存数值obj -> a = (int*)malloc(sizeof(int) * (k + 1));//多开一个空间,实现”假溢出“obj -> front = 0;//队首和队尾的下标都初始化为0obj -> rear = 0;obj -> k = k;//传入接口函数的大小kreturn obj;
}

3.3判断是否为空 和 判断是否为满

我们可以让front == rear时,循环队列为空。那么怎么判断是否为满呢?
我们可以多开一个空间这个空间不存放任何值,当rear + 1 == front时,则循环队列为满,这种现象叫做“假溢出”
这就是我们为什么要多开一个空间,目的就是利用假溢出来判断循环队列是否为满。

判空:
在这里插入图片描述

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

判满:(需要注意一些情况)

正常情况:这种情况只需判断rear + 1 == front 是否成立就可以了。

在这里插入图片描述

特殊情况:下面这种情况当rear + 1时,就会造成数组的越界。这时候就需要用到我们上面提到的 % 操作。
(rear + 1) % (k + 1) == front,可以让等号左边的值在0 ~ k 中循环,避免越界的情况。
如下图 front的下标为0,rear的下标为5,k为5 (5 + 1) % (5 + 1) == 0,可以看到可以成功判满。
利用 % 操作,不管时那种情况都能准确判断是否为满。

在这里插入图片描述

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

4. 进队列 和 出队列

进队列前,注意判断队列是否为满。
和普通队列一样,进队列让队尾++就可以了,注意当rear在末尾时越界情况。

当rear++后,可能会越界,此时rear应该在0下标处
同样可以进行 % 操作 rear %= k + 1
在这里插入图片描述

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj)) return false; //如果队列已满则入队列失败,返回falseobj -> a[obj -> rear++] = value; //进队列以后,rear++obj -> rear %= obj -> k + 1;//防止越界情况return true;//进队列成功返回true
}

出队列前,也应该判断队列是否为空,为空则返回false,表示出队列失败
和普通队列一样,出队列让队首++就可以了,注意越界情况

此时front应该在0下标处
%操作 front %= k + 1 即可
在这里插入图片描述

int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)) return -1;return obj -> a[obj -> front];
}

5.取队首和队尾元素

取队首元素很简单,直接取下标对应位置的值就可以了

int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)) return -1;//判空return obj -> a[obj -> front];
}

取队尾元素比较麻烦一点,因为rear位置是不存放值的所以队尾元素实际是 rear 的前一个位置

下图的队尾是rear 的前一个位置的元素,也就是44,一般情况下rear-1就可以得到队尾元素。
这里是特殊情况,同样利用%操作
(rear - 1 + k + 1) % (k + 1),也就是
(rear + k) % (k + 1),就可得到适应各种情况的获取队尾下标方法。
在这里插入图片描述

int myCircularQueueRear(MyCircularQueue* obj) { //尾不是rear,而是rear的前一位if(myCircularQueueIsEmpty(obj)) return -1;return obj -> a[(obj -> rear + obj -> k ) % (obj -> k + 1)];
}

6.释放空间

void myCircularQueueFree(MyCircularQueue* obj) {free(obj -> a); //先释放我们创建的数组free(obj);//再释放我们创建的结构
}

7.总结

设计循环队列,要设计好判空和判满情况。
其中,判满要利用“假溢出”这一特性。
利用数组设计循环队列的时候,利用%操作来达成我们的“循环”


http://www.ppmy.cn/news/12219.html

相关文章

TCP/IP网络编程(4)——基于 TCP 的服务端/客户端(1)

文章目录第 4 章 基于 TCP 的服务端/客户端(1)4.1 理解 TCP 和 UDP4.1.1 TCP/IP 协议栈4.1.2 链路层4.1.3 IP 层4.1.4 TCP/UDP 层4.1.5 应用层4.1.6 生活小例子4.2 实现基于 TCP 的服务器/客户端4.2.1 TCP 服务端的默认函数的调用程序4.2.2 进入等待连接…

57 mac 中 SIGINFO 信号, jdk8 支持, 但是 jdk9 不支持?

前言 问题来自于文章 shell脚本 后台启动 程序1 “tail -f log“, ctrl c 导致程序1中断 中的测试用例 Test07Signal2ParentProcess, 可以看到 我当时标记了一个 "todo, not work in hostpostVM9" 然后 问题是这样的, 我同一台机器, 然后 jdk8 带上 SIGINFO 去执行…

时间序列模型SCINet(代码解析)

前言 SCINet模型,精度仅次于NLinear的时间序列模型,在ETTh2数据集上单变量预测结果甚至比NLinear模型还要好。在这里还是建议大家去读一读论文,论文写的很规范,很值得学习,论文地址SCINet模型Github项目地址&#xff…

智能售货机系统帝可得

智能售货机 概述项目使用springcloudalibaba中提供的短信服务图形验证码生成多端登录/网关统一鉴权对象存储服务代码的自动填充微服务集成emq,发送emq工单业务流 接收工单 拒绝工单 运维工单补货工单使用xxl-job进行任务调度lkd集成xxl-job自动创建维修工单自动…

线程池(关于变量捕获、线程数、针对ThreadPoolExecutor的构造方法参数的解释、自实现线程池)

目录:一、前言二、关于变量捕获三、针对ThreadPoolExecutor的构造方法参数的解释四、自实现线程池一、前言相比较于进程,创建线程 / 销毁线程 的开销是相对较小的,但是太过频繁的创建线程 / 销毁线程,其开销也很大。这时候我们就需…

JVM-【面试题】-垃圾收集算法+垃圾收集器,以后就不用担心对象那些事了

一、垃圾收集算法在jvm里对可回收的对象在不同的垃圾收集器里,有不同的回收算法,具体的可以分为这四种:分代收集算法、复制算法、标记清除算法、标记整理算法1.1 分代收集算法当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有…

每日一问-ChapGPT-20230114-关于小年

文章目录每日一问-ChapGPT系列起因每日一问-ChapGPT-20230114-关于小年腊月每天都做些什么的歌谣为什么现在的年味淡了很多,感觉不到过年为什么春节放假要调休,不能多放几天吗说说现在世界上极端气候,以及多少年后,地球存在不适宜…

P3654 First Step (ファーストステップ)

P3654 First Step (ファーストステップ) 题目背景 知らないことばかりなにもかもが(どうしたらいいの?) 一切的一切 尽是充满了未知数(该如何是好) それでも期待で足が軽いよ(ジャンプだ!&…