力扣232 - 用栈实现队列【C语言实现】

news2024/9/23 3:15:51

用栈实现队列~

  • 一、题目描述
  • 二、思路分析
  • 三、代码详解
    • 1、结构声明与展开剖析
    • 2、入队【入栈思想】
    • 3、获取队头【出栈思想】
    • 4、出队【复用思想】
    • 5、逐步算法图解
  • 四、整体代码展示
    • 💻C语言代码实现
  • 五、总结与提炼

一、题目描述

在这里插入图片描述

示例 1:

输入:
[“MyQueue”, “push”, “push”, “peek”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

提示

  • 1 <= x <= 9
  • 最多调用 100 次 push、pop、peek 和 empty
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

二、思路分析

可以先看看这一篇:用队列实现栈

好,看完题目的描述,我们来分析一下去求解这道题目

  • 我们知道,栈与队列的原理刚好相反,对于栈是【FILO】,对于队列是【FIFO】。这就需要我们灵活地去使用这两种数据结构进行解题。对于本题,我的思路是这样的: 因为需要使用栈来实现队列,那还需要像我们上一题那样将两个队列倒来倒去实现一个出栈的操作吗?
  • 答案是:不需要,对于这一题而言,我们需要有一个明确的思路,也是去定义两个栈,一个栈专门入数据,一个栈专门出数据,具体的实现在下面👇

三、代码详解

1、结构声明与展开剖析

  • 可以看到,【StIn】是专门用来入数据的,【StOut】是专门用来出数据的;接着看到初始化创建这一块,一样对这两个栈进行一个初始化,首先由【qu】访问到这个两个栈,接着传入相应的地址进行初始化操作
typedef struct {
    ST stIn;
    ST stOut;
} MyQueue;
MyQueue* myQueueCreate() {
    MyQueue* qu = (MyQueue *)malloc(sizeof(MyQueue));
    InitStack(&qu->stIn);
    InitStack(&qu->stOut);

    return qu;
}
  • 以下是这个结构的整体形式

在这里插入图片描述


  • 然后的话来讲几个重要的接口算法实现

2、入队【入栈思想】

  • 首先的话就是这个入队了,因为我们使用栈来模拟,而且有专门只入数据的栈,因此直接将要放入队列的数据放到这个【StIn】中即可
PushStack(&obj->stIn, x);       //入栈操作均放入stIn

3、获取队头【出栈思想】

  • 接下去在首先讲出队操作之前我先讲讲如果获取队头这个接口,也就是peek()
  • 首先你会想到的一定是直接去调用我们栈中的Top()这个接口,去【StOut】中取数据,确实是可以取出来,但是当这个【StOut】为空的时候怎么办呢?因为需要去做一个处理
return StackTop(&obj->stOut);
  • 但这个【StOut】为空的时候,我们就可以将【StIn】中的数据放入【StOut】中,直至【StIn】为空为止。因为我们规定过【StIn】只入数据,【StOut】只出数据,所以要将这个【StIn】中的数据都倒到【StOut】中才可(这句话看清楚了,不要被我绕晕😵,或者你直接看代码吧)
if(StackEmpty(&obj->stOut))     //如果stOut为空,则进行一个倒栈操作
{
    while(!StackEmpty(&obj->stIn))
    {
        PushStack(&obj->stOut, StackTop(&obj->stIn));
        PopStack(&obj->stIn);
    }
}

4、出队【复用思想】

  • 有了【peek()】这个接口,我们在实现出队接口的时候就不需要再去写一个了,只需要去进行一个复用即可。接着Pop()出【StOut】中的一个数据
int peek = myQueuePeek(obj);
PopStack(&obj->stOut);

return peek;

5、逐步算法图解

  • 接下去我们通过算法图解来步步分析一下,首先看到【StOut】为空,因为需要将【StIn】中的数据尽数放入其中

在这里插入图片描述

  • 接着的话当全部数据一一过来后可以看到所有数据刚好实现了一个逆置的效果,接着出栈栈顶元素即可,就可以实现队列的一个FIFO的性质🎋

在这里插入图片描述

  • 继续入两个数据

在这里插入图片描述

  • 当连续执行完3次出队后,可以看到出队的顺序就是先进先出,接下去要继续出数据,因为【StOut】空了,所以继续将刚入的9和7放进来

在这里插入图片描述

在这里插入图片描述

  • 最后出队完成后就是利用两个栈实现的模拟队列入队出队后的序列

在这里插入图片描述

四、整体代码展示

💻C语言代码实现

  • 题目代码使用的是C语言实现
typedef int STDataType;
typedef struct Stack {
	STDataType* a;
	int top;		//栈顶指针
	int capacity;	//容量
}ST;

/*初始化栈*/
void InitStack(ST* st);

/*销毁栈*/
void DestroyStack(ST* st);

/*入栈*/
void PushStack(ST* st, STDataType x);

/*出栈*/
void PopStack(ST* st);

/*返回栈顶元素*/
STDataType StackTop(ST* st);

/*判空*/
bool StackEmpty(ST* st);

/*栈的元素个数*/
int StackSize(ST* st);

//--------------------------------
typedef struct {
    ST stIn;
    ST stOut;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* qu = (MyQueue *)malloc(sizeof(MyQueue));
    InitStack(&qu->stIn);
    InitStack(&qu->stOut);

    return qu;
}

void myQueuePush(MyQueue* obj, int x) {
    PushStack(&obj->stIn, x);       //入栈操作均放入stIn
}

bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->stIn) && StackEmpty(&obj->stOut);
}

int myQueuePop(MyQueue* obj) {
    int peek = myQueuePeek(obj);
    PopStack(&obj->stOut);

    return peek;
}

int myQueuePeek(MyQueue* obj) {
    if(StackEmpty(&obj->stOut))     //如果stOut为空,则进行一个倒栈操作
    {
        while(!StackEmpty(&obj->stIn))
        {
            PushStack(&obj->stOut, StackTop(&obj->stIn));
            PopStack(&obj->stIn);
        }
    }
    return StackTop(&obj->stOut);
}

void myQueueFree(MyQueue* obj) {
    DestroyStack(&obj->stIn);
    DestroyStack(&obj->stOut);

    free(obj);
}

//--------------------------------
/*初始化栈*/
void InitStack(ST* st)
{
	assert(st);		//警惕随意操作,传入空指针
	st->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (st->a == NULL)
	{
		perror("fail mallic");
		exit(-1);
	}
	st->top = 0;		//初始化为0表示指向当前栈顶元素的后一元素
	st->capacity = 4;
}

/*销毁栈*/
void DestroyStack(ST* st)
{
	assert(st);
	free(st->a);
	st->a = NULL;
	st->top = st->capacity = 0;
}

/*入栈*/
void PushStack(ST* st, STDataType x)
{
	//栈满扩容逻辑
	if (st->top == st->capacity)
	{
		//初始化时已经malloc开辟过空间了,因此无需考虑容量为空的情况
		STDataType* tmp = (STDataType*)realloc(st->a, st->capacity * 2 * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("fail realloc");
			exit(-1);
		}
		st->a = tmp;
		st->capacity *= 2;
	}
	st->a[st->top] = x;		//top指向栈顶元素的后一元素,因此直接入栈即可
	st->top++;		//然后栈顶指针后移,为下一次入栈做准备
}

/*出栈*/
void PopStack(ST* st)
{
	assert(st);
	//assert(st->top > 0);
	assert(!StackEmpty(st));

	st->top--;
}

/*返回栈顶元素*/
STDataType StackTop(ST* st)
{
	return st->a[st->top - 1];
}

/*判空*/
bool StackEmpty(ST* st)
{
	return (st->top == 0);
}

/*栈的元素个数*/
int StackSize(ST* st)
{
	return st->top;
}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/

五、总结与提炼

  • 最后我们来总结一下本文所介绍的内容,本文讲解的是一道力扣中有关栈与队列相关的题目,使用的栈来实现队列,对于本题,和上题使用队列来实现栈不同的是我们不需要去判断哪个是否为空,对于本题来说,我们只需要往【StIn】中入数据,往【StOut】中出数据即可,就可以实现模拟队列的操作

以上就是本文所要描述的所有内容,感谢您对本文的观看,如有疑问请于评论区留言或者私信我都可以🍀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java基础知识+必考面试题(分享收藏版)

在学习Java语言之前&#xff0c;我们要了解相关知识体系&#xff0c;才能更好的掌握学习。那么下面我们就一起来学习JAVA语言吧~ Java语言概述 Java语言是Sun公司在1995年推出的高级编程语言&#xff0c;编程语言就是计算机语言&#xff0c;人们可以通过使用编程语言让计算机完…

Webfunny 创始人:Skywalking × Zabbix 与观纵探索可观测性

作为 Webfunny 的 PMC&#xff0c;应伟长期致力于前端监控、埋点探针的产品研发&#xff0c;伴随着全链路监控的探索&#xff0c;在整合 Skywalking 与 Zabbix 打造一体化监控平台的实践中&#xff0c;是怎样的心路历程&#xff1f; “ 从前端监控到全链路监控的挑战 Webfun…

Mockplus Cloud updated传达设计意图的新方法

Mockplus Cloud updated传达设计意图的新方法 增加了Mockplus Cloud UI 2.0&#xff0c;使UI更加直观和简洁。 引入了注解&#xff0c;为向开发人员传达设计意图提供了一种新的方式。 添加了上传图像以进一步解释任务注释的功能。 优化任务创建以改善用户体验。 提高了下载、导…

BUUCTF·鸡藕椒盐味·WP

来源&#xff1a;https://buuoj.cn/challenges#%E9%B8%A1%E8%97%95%E6%A4%92%E7%9B%90%E5%91%B3 分析 鸡藕椒盐味奇偶校验位 ~验证码如下&#xff1a;1100 1010 0000 ,而且打印的时候倒了一下。把答案哈希一下就可以提交了~ 验证码是二进制数&#xff0c;但是题目也提示了这…

【Linux】了解系统整体状态-top命令

Top命令 查看系统整体状态&#xff0c;只能查看当前系统的大概情况 整个机器CPU 内存使用情况 IO使用情况 CPU(s)&#xff1a;0.0% CPU使用情况 %us&#xff1a;user CPU time 用户占用CPU百分比 %sy&#xff1a;system CPU time 内核空间占用CPU百分比 %ni&#x…

Node的web编程(三)

一、jQuery中对ajax封装 1、底层封装&#xff1a;封装了XMLHttpRequest对象&#xff0c;既可以发送get请求&#xff0c;也可以发送post请求 $.ajax({ url&#xff1a;服务器地址, type&#xff1a;请求方式, data&#xff1a;{ //客户端向服务器发送的请求数据 参数名1&#x…

SolidWorks弯曲的波纹管制作教程

如何使用SolidWorks制作波纹管呢?可能很多小伙伴都会做,那完全的波纹管如何制作呢?有的小伙伴可能不止一种方法,可能有很多方法,可以用扫描路径等,下面我用其他方法去实现下面效果图 首先新建一个零件,选前视基准面,画一个40MM的圆,如下图 然后用拉伸凸台命令,长度给…

.net----结构和枚举

结构和枚举结构结构的声明和调用声明调用结构&#xff1a;结构的成员枚举枚举的使用枚举&#xff1a;Flags枚举结构 轻量级的类&#xff0c;与类很相似&#xff0c;均为包含数据成员和函数成员的数据结构 结构与类的区别 结构是值类型且被称为具有值语义&#xff1b;而类是引…

【Lilishop商城】No2-2.确定软件架构搭建一(本篇包括MVC框架、持久框架、缓存、认证工具、安全框架等)

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 上一篇已经看了项目的开发架构&#xff0c;都需要哪些技术&#xff0c;都按照哪些规范&#xff0c;都哪…

免杀Backdoor-factory

Patch ● 通过替换EXE、DLL、注册表等方法修复系统漏洞或问题的方法 ● BDF&#xff1a;向二进制文件中增加或者删除代码内容 ○ 某些受保护的二进制程序无法patch ○ 存在一定概率文件会被patch坏掉 后门工厂 ● 适用于windows PE x32/x64和Linux ELF x32/x64(OSX) ● 支持…

【JVM】内存模型:原子性、可见性、有序性的问题引出与解决

一、内存模型 很多人将【java 内存结构】与【java 内存模型】傻傻分不清&#xff0c;【java 内存模型】是 Java MemoryModel&#xff08;JMM&#xff09;的意思。 简单的说&#xff0c;JMM 定义了一套在多线程读写共享数据时&#xff08;成员变量、数组&#xff09;时&#x…

(七)RabbitMQ持久化

RabbitMQ持久化1、概念2、队列持久化3、消息持久化4、不公平分发5、预取值1、概念 默认情况下 RabbitMQ 退出或由于某种原因崩溃时&#xff0c;它忽视队列和消息&#xff0c;除非告知它不要这样做。确保消息不会丢失需要做两件事&#xff1a;我们需要将队列和消息都标记为持久化…

广义OOD检测最新综述

arXiv在2021年10月21日上传的论文**“Generalized Out-of-Distribution Detection: A Survey“&#xff0c;作者来自新加坡的南洋理工大学&#xff08;NTU&#xff09;和美国的威斯康星大学Madison分校**。 OOD检测对确保机器学习系统的可靠性和安全性至关重要&#xff0c;例如…

秦皇岛科学选育新品种 国稻种芯·中国水稻节:河北谱丰收曲

秦皇岛科学选育新品种 国稻种芯中国水稻节&#xff1a;河北谱丰收曲 冀时客户端报道&#xff08;河北台 张志刚 米弘钊 赵永鑫&#xff09; 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 国稻种芯中国水稻节 中国农民丰收节国际贸易促进会 中国三农智库网-功能性农业农业…

Java对象拷贝原理剖析及最佳实践

作者&#xff1a;宁海翔 1 前言 对象拷贝&#xff0c;是我们在开发过程中&#xff0c;绕不开的过程&#xff0c;既存在于Po、Dto、Do、Vo各个表现层数据的转换&#xff0c;也存在于系统交互如序列化、反序列化。 Java对象拷贝分为深拷贝和浅拷贝&#xff0c;目前常用的属性拷…

2023年系统规划与设计管理师-学习计划安排

一.学习计划和安排&#xff1a; 序号 学习内容 分数以及题型 学习安排 完成日期 1 浏览教程&#xff0c; 了解知识结构 1天 11/24 2 前三章内容&#xff1a; 课本&#xff0c; 单元练习&#xff0c; 思维导图&#xff0c; 总结归纳&#xff0c; 第一遍背诵 分数占…

希望所有计算机学生都知道这些宝藏课程

数据结构 青岛大学——王卓老师的数据结构与算法基础 浙江大学——陈越、何钦铭老师的数据结构课程 清华大学——邓俊辉老师的数据结构课程 北京大学——数据结构基础课程 操作系统 哈工大——李治军老师的操作系统 清华大学——操作系统原理 南京大学——操作系统概述 计算…

机器学习知识经验分享之一:卷积神经网络介绍

文章目录前言一、卷积神经网络的构成1.卷积层2.池化层3.激活函数4.批量归一化5.损失函数二、卷积神经网络的特点总结前言 本系列文章将对机器学习知识进行分享总结。便于大家从理论层面了解人工智能基础原理&#xff0c;从而更好的运用算法发论文写作以及实际应用。关注即免费…

CNI设计解读

何为cni&#xff1f; kubernetes在设计网络方案的时候并没有设计统一的网络方案&#xff0c;只提供了统一的容器网络接口也就是所谓cni&#xff0c;这么做的目的就是为了遵循kubernets的核心理念OutOfTree&#xff0c;简单来讲就是专注于自身核心能力&#xff0c;将其他能力类…

使用albumentations对coco进行数据增强

数据增强的必要性 目前几乎所有描述最先进的图像识别模型的论文都使用了基本的增强技术 深度神经网络需要大量的训练数据来获得良好的结果&#xff0c;并防止过度拟合&#xff0c;然而要获得足够的训练样本往往非常困难&#xff0c;多种原因可能使得收集足够的数据非常困难&a…