【leetcode】225.用队列实现栈

分析:
队列遵循先入先出的原则,栈遵循后入先出的原则
也就是说,使用队列实现栈时,入队操作正常,但是出队要模拟出栈的操作,我们需要访问的是队尾的元素;题目允许使用两个队列,我们可以先将存有数据的队列中除队尾元素外的所有元素依次出队,存入空队列中,再访问原队列中的队头元素即可
1.使用两个队列构造栈:
C语言中没有定义队列的结构,我们需要自定义队列及其相关操作
如下:结构MyStack由两个队列结构q1和q2构成
为我们创建的栈结构进行动态内存申请并进行初始化
//由两个队列构成栈结构
typedef struct {Queue q1;Queue q2;} MyStack;
//创建栈
MyStack* myStackCreate() {//myStack未具有两个队列的栈结构类型MyStack* obj = (MyStack*)malloc(sizeof(MyStack));//内存开辟失败if(obj == NULL){perror("malloc fail");exit(-1);}//开辟成功,初始化else{QueueInit(&obj->q1);QueueInit(&obj->q2);}return obj;
}
2.压栈操作
模拟栈的压栈操作,数据正常入队即可
📖Note:
我们要将数据插入非空的队列,保证每次都存在一个空队列可以进行数据的存储
void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}}
3.移除并返回栈顶元素
模拟栈的出栈操作:访问并移除的是非空队列的队尾元素
步骤:将存有数据的队列中除队尾元素外的所有元素依次出队,存入空队列中,再访问并移除原队列中的队头元素即可,如下图:
上述操作后,q1和q2的结构如下:
此时,将队列q1中的元素(相当于后入的栈顶元素)先存储,再出队列q1(即清空队列q1,供下次压栈操作使用),返回存储的值即可
int myStackPop(MyStack* obj) {Queue* empty = &obj->q1;Queue* nonempty = &obj->q2;if(!QueueEmpty(&obj->q1)){nonempty = &obj->q1; empty = &obj->q2; }//非空队列前n-1个入空队列并出队,剩下最后一个即为栈顶元素while(QueueSize(nonempty) > 1){QueuePush(empty,QueueFront(nonempty));QueuePop(nonempty);}int top = QueueFront(nonempty);QueuePop(nonempty);//清空队列return top;
}
4.返回栈顶元素
栈顶元素即非空队列的队尾数据
int myStackTop(MyStack* obj) { if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}
5.判断是否为空栈
myStack是由两个队列构成的栈结构,当两个队列都为空时栈即为空
bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
6.空间释放
创建栈时为其动态申请了空间,操作结束需要进行空间释放,否则会造成内存泄漏
void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);
}
完整参考代码如下:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;
}Queue;#define bool int
#define true 1
#define false 0//队列初始化
void QueueInit(Queue* pq);
//队列销毁
void QueueDestroy(Queue* pq);
//数据入队
void QueuePush(Queue* pq, QDataType x);
//数据出队
void QueuePop(Queue* pq);
//访问队头数据
QDataType QueueFront(Queue* pq);
//访问队尾数据
QDataType QueueBack(Queue* pq);
//判断队列是否为空
bool QueueEmpty(Queue* pq);
//求队列的大小
int QueueSize(Queue* pq);//队列初始化
void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;
}
//队列销毁
void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* del = cur;cur = cur->next;free(del);}pq->head = pq->tail = NULL;
}
//数据入队
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}else{newnode->data = x;newnode->next = NULL;}//空队列时插入if (pq->tail == NULL){pq->head = pq->tail = newnode;}//非空队列时插入else{pq->tail->next = newnode;//链接新元素pq->tail = newnode;//更新队尾}
}
//数据出队
void QueuePop(Queue* pq)
{assert(pq);//空队列不能进行出队操作assert(!QueueEmpty(pq));//队列中只有一个元素if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* del = pq->head;pq->head = pq->head->next;free(del);del = NULL;}
}
//访问队头数据
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;}
//访问队尾数据
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}
//判断队列是否为空
bool QueueEmpty(Queue* pq)
{assert(pq);/*if (pq->tail == pq->head == NULL){return true;}else{return false;}*/return pq->head == NULL && pq->tail == NULL;
}
//求队列的大小
int QueueSize(Queue* pq)
{assert(pq);int size = 0;QNode* cur = pq->head;while (cur){size++;cur = cur->next;}return size;
}//由两个队列构成栈结构
typedef struct {Queue q1;Queue q2;} MyStack;
//创建栈
MyStack* myStackCreate() {//myStack未具有两个队列的栈结构类型MyStack* obj = (MyStack*)malloc(sizeof(MyStack));//内存开辟失败if(obj == NULL){perror("malloc fail");exit(-1);}//开辟成功,初始化else{QueueInit(&obj->q1);QueueInit(&obj->q2);}return obj;
}
void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}}int myStackPop(MyStack* obj) {Queue* empty = &obj->q1;Queue* nonempty = &obj->q2;if(!QueueEmpty(&obj->q1)){nonempty = &obj->q1; empty = &obj->q2; }//非空队列前n-1个入空队列并出队,剩下最后一个即为栈顶元素while(QueueSize(nonempty) > 1){QueuePush(empty,QueueFront(nonempty));QueuePop(nonempty);}int top = QueueFront(nonempty);QueuePop(nonempty);//清空队列return top;
}
//栈顶元素即非空队列的队尾数据
int myStackTop(MyStack* obj) { if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);
}
相关文章:
【leetcode】225.用队列实现栈
分析: 队列遵循先入先出的原则,栈遵循后入先出的原则 也就是说,使用队列实现栈时,入队操作正常,但是出队要模拟出栈的操作,我们需要访问的是队尾的元素;题目允许使用两个队列,我们可…...
机器学习中XGBoost算法调参技巧
本文将详细解释XGBoost中十个最常用超参数的介绍,功能和值范围,及如何使用Optuna进行超参数调优。 对于XGBoost来说,默认的超参数是可以正常运行的,但是如果你想获得最佳的效果,那么就需要自行调整一些超参数来匹配你…...
第1章:计算机网络体系结构
文章目录 1.1 计算机网络 概述1.概念2.组成3.功能4.分类5.性能指标1.2 计算机网络 体系结构&参考模型1.分层结构2.协议、接口、服务3.ISO/OSI模型4.TCP/IP模型1.1 计算机网络 概述 1.概念 2.组成 1.组成部分&...
【Java 动态数据统计图】动态数据统计思路Demo(动态,排序,containsKey)三(115)
上代码: import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map;public class day10 {public static void main(String[] args) {List<Map<String,O…...
【游戏评测】河洛群侠传一周目玩后感
总游戏时长接近100小时,刚好一个月。 这两天费了点劲做了些成就,刷了等级,把最终决战做了。 总体感觉还是不错的。游戏是开放世界3D游戏,Unity引擎,瑕疵很多,但胜在剧情扎实,天赋系统、秘籍功法…...
java新特性之Lambda表达式
函数式编程 关注做什么,不关心是怎么实现的。为了实现该思想,java有了一种新的语法格式,Lambda表达式。Lambda本质是匿名内部类对象,是一个函数式接口。函数式接口表示接口内部只有一个抽象方法。使用该语法可以大大简化代码。 …...
【考研数学】线形代数第三章——向量 | 2)向量组相关性与线性表示的性质,向量组的等价、极大线性无关组与秩
文章目录 引言二、向量组的相关性与线性表示2.3 向量组相关性与线性表示的性质 三、向量组等价、向量组的极大线性无关组与秩3.1 基本概念 写在最后 引言 承接前文,我们来学习学习向量组相关性与线性表示的相关性质 二、向量组的相关性与线性表示 2.3 向量组相关性…...
Java中调用Linux脚本
在Java中,可以使用ProcessBuilder类来调用Linux脚本。以下是一个简单的示例,展示了如何在Java中调用Linux脚本: 创建一个Linux脚本文件(例如:myscript.sh),并在其中编写需要执行的命令。确保脚…...
Nexus 如何配置 Python 的私有仓库
Nexus 可作为一个代理来使用。 针对一些网络环境不好的公司,可以通过配置 Nexus 来作为远程的代理。 Group 概念 Nexus 有一个 Group 的概念,我们可以认为一个 Nexus 仓库的 Group 就是很多不同的仓库的集合。 从下面的配置中我们可以看到࿰…...
Maven 配置文件修改及导入第三方jar包
设置java和maven的环境变量 修改maven配置文件 (D:\app\apache-maven-3.5.0\conf\settings.xml,1中环境变量对应的maven包下的conf) 修改131行左右的mirror,设置阿里云的仓库地址 <mirror> <id>alimaven</id&g…...
jmeter CSV 数据文件设置
创建一个CSV数据文件:使用任何文本编辑器创建一个CSV文件,将测试数据按照逗号分隔的格式写入文件中。例如: room_id,arrival_date,depature_date,bussiness_date,order_status,order_child_room_id,guest_name,room_price 20032,2023-8-9 14:…...
【SA8295P 源码分析】20 - GVM Android Kernel NFS Support 配置
【SA8295P 源码分析】20 - GVM Android Kernel NFS Support 配置 系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》 本文链接:《【SA8295P 源码分析】20 - GVM Android Kernel NFS Support 配置》 # make menuconfigFile systems ---> [*] Network File Sy…...
c++都补了c语言哪些坑?
目录 1.命名空间 1.1 定义 1.2 使用 2.缺省参数 2.1 概念 2.2 分类 3.函数重载 4.引用 4.1 概念 4.2 特性 4.3 常引用 4.4 引用和指针的区别 5.内联函数 1.命名空间 在 C/C 中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将…...
【C语言】C语言用数组算平均数,并输出大于平均数的数
题目 让用户输入一系列的正整数,最后输入“-1”表示输入结束,然后程序计算出这些数的平均数,最后输出输入数字的个数和平均数以及大于平均数的数 代码 #include<stdio.h> int main() {int x;double sum 0;int cnt 0;int number[100…...
「UG/NX」Block UI 体收集器BodyCollector
✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#...
金九银十面试题之《JVM》
🐮🐮🐮 辛苦牛,掌握主流技术栈,包括前端后端,已经7年时间,曾在税务机关从事开发工作,目前在国企任职。希望通过自己的不断分享,可以帮助各位想或者已经走在这条路上的朋友…...
wireshark | 过滤筛选总结
wireshark 是一款开源抓包工具。比如与服务器的请求响应、tcp三次握手/四次挥手 场景:在linux环境下使用tcpdump -w 然后把爬的数据写入指定的XXX.pcap 然后在wireshark中导入该文件XXX.pcap 使用下面的过滤方式进行过滤 分析数据就可以了 #直接看 不需要硬背 和s…...
list使用
list的使用于string的使用都类似,首先通过查阅来看list有哪些函数: 可以看到函数还是蛮多的,我们值重点一些常用的和常见的: 1.关于push_back,push_front,和对应迭代器的使用 //关于push_back和push_front void test_list1() {l…...
【图解】多层感知器(MLP)
图片是一个多层感知器(MLP)的示意图,它是一种常见的神经网络模型,用于从输入到输出进行非线性映射。图片中的网络结构如下:...
React(8)
千锋学习视频https://www.bilibili.com/video/BV1dP4y1c7qd?p72&spm_id_frompageDriver&vd_sourcef07a5c4baae42e64ab4bebdd9f3cd1b3 1.React 路由 1.1 什么是路由? 路由是根据不同的 url 地址展示不同的内容或页面。 一个针对React而设计的路由解决方案…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...

上述操作后,q1和q2的结构如下: