【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而设计的路由解决方案…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...