【数据结构】如何用栈实现队列?图文解析(LeetCode)

LeetCode链接:232. 用栈实现队列 - 力扣(LeetCode)

注:本文默认读者已掌握栈与队列的基本操作

可以看这篇文章熟悉知识点:【数据结构】栈与队列_字节连结的博客-CSDN博客

目录

做题思路

代码实现

1. MyQueue

2. myQueueCreate

 3. myQueuePush

4. myQueuePeek

5. myQueuePop

6. myQueueEmpty

7. myQueueFree

全部代码


做题思路

简单来说,就是把一个栈(栈1)的数据捯入另一个栈(栈2),此时(栈2)出数据的顺序就和队列是一样的。

为了更方便理解,我会画图来演示一下具体思路。

我们需要两个栈来实现队列:

  • push栈:专门入数据的栈
  • pop栈:专门出数据的栈

如下图:

插入数据:直接在push栈内插入即可

push栈内插入数据:1、2、3、4、5

删除数据:需要把push栈内的数据捯入pop栈

  • 栈是后入先出的
  • 当push栈的数据捯入pop栈后,数据顺序会改变

如下图:

可以看到数据顺序逆转了

但是的这些操作跟队列有什么联系呢?

不妨来看看pop栈队列的对比:

由此可见:pop栈出数据的顺序是和队列一样的

到这里思路已经很清晰了:我们需要两个栈,一个专门用来push,一个专门用来pop,捯数据后,pop栈出数据的顺序就跟队列是一样的。

那么如何用代码(C)来实现这个思路呢?


代码实现

由于我们使用的是C语言,不能直接使用栈的操作

所以先把之前模拟实现过的栈复制过来:

//C语言模拟实现栈typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;//初始化栈
void STInit(ST* ps);
//销毁栈
void STDestroy(ST* ps);
//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);
//获取栈顶元素
STDataType STTop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}STDataType STTop(ST* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}int STSize(ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

复制完成之后就是本题的重点内容了。

本题要求:

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

1. MyQueue

由于我们是用两个栈实现队列

所以这里需要定义两个栈

//两个栈模拟实现队列
typedef struct
{ST pushst;ST popst;
} MyQueue;

2. myQueueCreate

这个函数要求我们开辟空间,并初始化栈

//开辟空间并初始化
MyQueue* myQueueCreate()
{MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);STInit(&obj->popst);return obj;
}

 3. myQueuePush

直接把数据插入到push栈即可

//将元素X推到队列的末尾
void myQueuePush(MyQueue* obj, int x)
{STPush(&obj->pushst, x);
}

4. myQueuePeek

本函数要求返回队列开头的元素

  • 如果pop栈为空:要把push栈的数据捯入pop栈才能找到队列的首元素
  • 如果pop栈不为空:pop栈的栈顶元素就是队列的首元素

//返回队列开头的元素
int myQueuePeek(MyQueue* obj)
{if (STEmpty(&obj->popst)){//捯数据while (!STEmpty(&obj->pushst)){STPush(&obj->popst, STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);
}

5. myQueuePop

  • 要求删除队头元素,也就是pop栈的栈顶元素,直接删除即可
  • 并且要返回队头元素的值,需要先定义一个临时变量来保存队头元素的值
  • 最后返回这个临时变量
//从队列的开头移除并返回元素
int myQueuePop(MyQueue* obj)
{int front = myQueuePeek(obj);STPop(&obj->popst);return front;
}

6. myQueueEmpty

判断队列是否为空,返回一个bool值(true/false)

如果push栈pop栈都为空,则说明队列为空

//如果队列为空,返回true;否则,返回false
bool myQueueEmpty(MyQueue* obj)
{return STEmpty(&obj->popst) && STEmpty(&obj->pushst);
}

7. myQueueFree

销毁队列

  • 销毁push栈pop栈
  • 释放动态开辟的空间
//销毁队列
void myQueueFree(MyQueue* obj)
{STDestroy(&obj->popst);STDestroy(&obj->pushst);free(obj);
}

到这里全部函数已经实现完毕,提交代码:

成功通过

下面我会把本题的全部代码整合在一起发出来


全部代码

//C语言模拟实现栈typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;//初始化栈
void STInit(ST* ps);
//销毁栈
void STDestroy(ST* ps);
//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);
//获取栈顶元素
STDataType STTop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}STDataType STTop(ST* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}int STSize(ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//=======================================================================//两个栈模拟实现队列
typedef struct
{ST pushst;ST popst;
} MyQueue;//开辟空间并初始化
MyQueue* myQueueCreate()
{MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);STInit(&obj->popst);return obj;
}//将元素X推到队列的末尾
void myQueuePush(MyQueue* obj, int x)
{STPush(&obj->pushst, x);
}//返回队列开头的元素
int myQueuePeek(MyQueue* obj)
{if (STEmpty(&obj->popst)){//捯数据while (!STEmpty(&obj->pushst)){STPush(&obj->popst, STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);
}//从队列的开头移除并返回元素
int myQueuePop(MyQueue* obj)
{int front = myQueuePeek(obj);STPop(&obj->popst);return front;
}//如果队列为空,返回true;否则,返回false
bool myQueueEmpty(MyQueue* obj)
{return STEmpty(&obj->popst) && STEmpty(&obj->pushst);
}//销毁队列
void myQueueFree(MyQueue* obj)
{STDestroy(&obj->popst);STDestroy(&obj->pushst);free(obj);
}

本文完​​​​​​​

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】从入门到上头—Python基础(2)

文章目录 一.基础语法1.编码2.标识符3.保留字4.注释5.行与缩进6.多行语句7.数字(Number)类型8.字符串(String)9.空行10.等待用户输入11.同一行显示多条语句12.多个语句构成代码组13.print 输出14.import 与 from...import 二.基本数据类型1.变量和赋值2.多个变量赋值3.标准数据…

2023.8 -java - 继承

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。 继承的特性 子类拥有父类非 private 的属性、方法。 子类可以拥有自己的属性和方法…

数据库连接池druid 的jar包官网下载-最新版下载

进入官网Central Repository: com/alibaba/druid 往下滑 找到最新版点击进入 找到该jar包 点击即可下载

【HCIP】04.VRRP与BFD

VRRP VRRP基本概念 VRRP路由器 运行VRRP协议的路由器,VRRP是配置在路由器的接口上的,而且也是基于接口来工作的。 VRID 一个VRRP组由多台协同工作的路由器(的接口)组成,使用相同的VRID(Virtual Router…

视频转gif制作怎么制作?视频转gif在线一键转换工具

gif图片可以用于网站和应用程序的界面设计,通过将视频内容转换为gif图像,可以在网站加载过程中显示加载动画、创建交互效果或提供引导,所以今天分享一个快速视频转gif图片(https://www.gif.cn)的方法,利用视…

API 网关基础

目录 一、网关概述二、网关提供的功能三、常见网关系统3.1 Netflix Zuul3.2 Spring Cloud Gateway3.3 Kong3.4 APISIX3.5 Shenyu 一、网关概述 API网关是一个服务器,是系统的唯一入口。 从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部…

8、Spring_整合Mybatis

五、Spring整合Mybatis 1.添加依赖 添加依赖 <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.17.RELEASE</version></dependency><depend…

00-音视频-概述

有很多场合会使用的音视频&#xff0c;比如安防、视频闸机、影音播放器、视频通话&#xff0c;短视频等等。 从摄像头采集到用户观看&#xff0c;这中间涉及到了很多技术。 用户一般观看的高清视频1080P30帧。若按24位RGB对视频进行存储&#xff0c;一个60分钟视频所占空间 …

百度工程师浅析解码策略

作者 | Jane 导读 生成式模型的解码方法主要有2类&#xff1a;确定性方法&#xff08;如贪心搜索和波束搜索&#xff09;和随机方法。确定性方法生成的文本通常会不够自然&#xff0c;可能存在重复或过于简单的表达。而随机方法在解码过程中引入了随机性&#xff0c;以便生成更…

什么是数据中心IP,优缺点是什么?

如果根据拥有者或者说发送地址来分类的话&#xff0c;可以将代理分为三类&#xff1a;数据中心ip,住宅ip,移动ip 本文我们来了解数据中心ip的原理以及他们的优势劣势&#xff0c;才能选择适合自己的代理。 一、什么是数据中心ip代理&#xff1f; 数据中心ip是由数据中心拥有…

15. Canvas制作汽车油耗仪表盘

1. 说明 本篇文章在14. 利用Canvas组件制作时钟的基础上进行一些更改&#xff0c;想查看全面的代码可以点击链接查看即可。 效果展示&#xff1a; 2. 整体代码 import QtQuick 2.15 import QtQuick.Controls 2.15Item{id:rootimplicitWidth: 400implicitHeight: implicitWi…

精准高效农业作业,植保无人机显身手

中国作为农业大国&#xff0c;拥有约18亿亩的农田&#xff0c;每年都需要进行种子喷洒和农药施用等农业作业&#xff0c;对于普通农户来说&#xff0c;这是一项耗时耗力的工程&#xff0c;同时&#xff0c;人工喷洒农药极易造成农药慢性中毒&#xff0c;对农民的身体健康产生极…

Unity3D软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Unity3D是一款全球知名的游戏开发引擎&#xff0c;由Unity Technologies公司开发。它提供了一个跨平台、多功能的开发环境&#xff0c;支持创建2D和3D游戏、交互式应用、虚拟现实、增强现实等多种类型的应用程序。以下是Unity3D…

ChatGPT在高等教育中的应用利弊探讨

​人工智能在教育领域的应用日益广泛。2022年11月OpenAI开发的聊天机器人ChatGPT在全球范围内流传开来&#xff0c;其中用户数量最多的国家是美国(15.22%)。由于ChatGPT应用广泛&#xff0c;具有类似人类回答问题的能力&#xff0c;它正在成为许多学生和教育工作者的可信赖伙伴…

本地生活服务平台加盟哪家公司好?

本地生活的竞争从年初的火热到现在&#xff0c;已经进入了下半场&#xff0c;随着优胜劣汰的筛选&#xff0c;那么直到现在&#xff0c;想做本地生活服务平台加盟&#xff0c;哪家公司比较好呢&#xff0c;应该如何选择呢&#xff1f; 首先我们得弄懂&#xff0c;我们加盟本地…

《向量数据库指南》——什么叫“AI 向量数据库”,它和我们日常理解的数据库有什么不同?

我认为"AI 向量数据库"这个概念非常切合实际,它类似于关系数据库在交易领域的作用。个人观点是,向量数据库实际上是为了人工智能而生的。一方面,向量数据库的数据完全源自于人工智能技术。另一方面,对于 AI 应用而言,向量数据库也是至关重要的基础设施。 至于…

idea http request无法识别环境变量

问题描述 创建了环境变量文件 http-client.env.json&#xff0c;然后在*.http 文件中引用环境变量&#xff0c;运行 HTTP 请求无法读取环境变量文件中定义的变量。 事故现场 IDEA 版本&#xff1a;2020.2 2021.2 解决步骤 2020.2 版本环境变量无法读取 2021.2 版本从 2020.…

【Java笔记】分布式id生成-雪花算法

随着业务的增长&#xff0c;有些表可能要占用很大的物理存储空间&#xff0c;为了解决该问题&#xff0c;后期使用数据库分片技术。将一个数据库进行拆分&#xff0c;通过数据库中间件连接。如果数据库中该表选用ID自增策略&#xff0c;则可能产生重复的ID&#xff0c;此时应该…

探索数据的维度:多元线性回归在实际应用中的威力

文章目录 &#x1f340;引言&#x1f340;什么是多元线性回归&#xff1f;&#x1f340;多元线性回归的应用&#x1f340;构建多元线性回归模型的步骤&#x1f340;R-squared&#xff08;R平方&#xff09;&#x1f340;多元线性回归案例---波士顿房价 &#x1f340;引言 当谈…

从0开始做yolov5模型剪枝

文章目录 从0开始做yolov5模型剪枝 ****1 前言2 GitHub取源码3 原理3.1 原理3.2 network slimming过程 4 具体实施步骤4.1 安装虚拟环境4.2 配置参数4.2.1 数据集参数4.2.2 模型结构参数4.2.3 train.py中的参数 4.3 正常训练4.3.1 准备4.3.2 训练及问题解决 4.4 稀疏化训练4.4.…