【数据结构】栈和队列-相互实现OJ题

前言:

本题目是关于栈和队列的OJ题目,需对栈和队列有一定了解再进行做题,若不了解可以根据我之前这篇文章进行学习:【数据结构】栈和队列-CSDN博客,题中需要的栈和队列的实现也在该文章中有源代码

目录

前言:

一.用队列实现栈

1.解题思路

2.解题代码

二.用栈实现队列

1.解题思路

2.解题代码

法一:

法二:


一.用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode)

1.解题思路

栈和队列区别在于出数据时的不同,栈遵循“后入先出”,而队列遵循“先入先出”,但在入数据时并没有不同,因此在Push时只需要依照队列的Push即可,将数据进入一个队列。

而在出数据时就不能直接出该队列的数据了,因为此处是模拟栈,需要移除的是队列中的最后一位(最晚进)的数据,而队列只能对队首的数据进行出操作,那么此时第二个队列(此时为空)就有用处了,将第一个队列(有数据的队列)的队首数据插入到第二个队列中,再进行出队,直到第一个队列仅剩最后一个数据(这个数据就是出栈操作要移除的数据),移除该数据不进行插入到第二个队列,如此第一个队列为空,第二个队列就是进行出栈操作后的结果了。

下图大致能演示这个模拟出栈的过程

2.解题代码

队列的实现前言中有,这里不贴出来浪费篇幅了。明白了上图所示的思路,那么整道题就好解决了。关键在于将两个队列分为空队列和非空队列,入栈时与入队操作相同,直接对非空队列(都为空则默认一个)入队即可,出栈时进行两队列的数据交换,其余函数根据两队列性质来即可。

typedef struct {Queue q1;Queue q2;  
} MyStack;//初始化
MyStack* myStackCreate() {MyStack* s = (MyStack*)malloc(sizeof(MyStack));QueueInit(&(s->q1));QueueInit(&(s->q2));return s;
}//判断非空与否的条件就是两个队列是否都为空
bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}//入栈,与入队是相同的操作,只需要向非空的队列入队即可
void myStackPush(MyStack* obj, int x) {if(QueueEmpty(&obj->q1)){QueuePush(&obj->q2,x);}else{QueuePush(&obj->q1,x);}}//出栈,找到非空队列和空队列进行转换
//注:返回值int是栈顶数据,也就是非空队列的队尾数据(移动后最后一个数据,同时也是队首)
int myStackPop(MyStack* obj) {//找到空队列和非空队列Queue* empty = &(obj->q1);Queue* notempty = &(obj->q2);if(QueueEmpty(&obj->q2)){empty = &obj->q2;notempty = &obj->q1;}while(QueueSize(notempty)>1){QueuePush(empty,QueueFront(notempty));QueuePop(notempty);}int ret = QueueFront(notempty);QueuePop(notempty);return ret;
}//栈顶数据就是非空队列的队尾数据
int myStackTop(MyStack* obj) {if(QueueEmpty(&obj->q1)){return QueueBack(&obj->q2);}else{return QueueBack(&obj->q1);}
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}

 

二.用栈实现队列

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

1.解题思路

与上道题同理,这次只是反了过来,用栈来实现队列,思路完全可以照搬,区别只在于用出栈模拟出队,不过有一点有差异,取出的栈顶元素(如图中4)插入到Stack2中顺序是相反的,因此需要来转换一下,这里我利用了数组下标进行转化的方法,具体实现方法在下文的方法一中。

 

不过这种方法比较麻烦,也不美观,破坏了封装性,不推荐。在这里给出另一个更为巧妙的方法,直接将两个Stack分为Pushst(插入)和Popst(删除)两个栈,分别对应插入删除,同样能实现。在需要 删除时将Pushst中的数据倒如Popst中即可。巧妙的点在于倒数据的过程中,恰巧使得顺序颠倒,而出栈正好就满足了出队的要求,就如下图所示,具体代码在下方法二。

2.解题代码

法一:

本方法与前一题的方法如出一辙,思路简单,但不推荐。

typedef struct {ST s1;ST s2;
} MyQueue;//初始化
MyQueue* myQueueCreate() {MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));STInit(&q->s1);STInit(&q->s2);return q;
}//对非空栈进行入栈
void myQueuePush(MyQueue* obj, int x) {if(STEmpty(&obj->s1)){STPush(&obj->s2,x);}else{STPush(&obj->s1,x);}
}//出栈
int myQueuePop(MyQueue* obj) {//找出非空栈和空栈ST* empty = &obj->s1;ST* notempty = &obj->s2;if(STEmpty(&obj->s2)){empty = &obj->s2;notempty = &obj->s1;}//注意此处要用size保存,否则在后续循环内STPop时top变化会导致错误int size = notempty->top;//移入空栈(顺序是正确的)for(int i = 1;i<size;i++){STPush(empty,notempty->a[i]);}//得到返回的数据,并将原非空栈Pop为空int ret = notempty->a[0];for(int i = 0;i<size;i++){STPop(notempty);}return ret;
}int myQueuePeek(MyQueue* obj) {if(STEmpty(&obj->s1)){return obj->s2.a[0];}else{return obj->s1.a[0];}
}bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->s1) && STEmpty(&obj->s2);
}void myQueueFree(MyQueue* obj) {STDestroy(&obj->s1);STDestroy(&obj->s2);
}

法二:

推荐该方法,更为巧妙简单。

typedef struct {ST Pushst;ST Popst;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));STInit(&q->Pushst);STInit(&q->Popst);return q;
}//插入直接向Pushst插入即可
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);
}//需要取得队首,使用peek既可以倒数据,又能得到队首数据,一举两得
int myQueuePop(MyQueue* obj) {int ret = myQueuePeek(obj);STPop(&obj->Popst);return ret;
}bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->Pushst) && STEmpty(&obj->Popst);
}void myQueueFree(MyQueue* obj) {STDestroy(&obj->Pushst);STDestroy(&obj->Popst);
}

两种方法均能通过该题的全部样例。 

 

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

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

相关文章

怎样将word默认Microsoft Office,而不是WPS

设置——>应用——>默认应用——>选择"word"——>将doc和docx都选择Microsoft Word即可

面试题-Spring家族与SpringIOC

1.spring家族的介绍 Spring简单图&#xff1a; 2.IOC原理 IOC就是原先代码里需要开发者实现对象的创建和关系依赖&#xff0c;反转交给SpringIOC容器管理对象的生命周期和对象之间的依赖关系。 依赖注入的方式&#xff1a; Setter&#xff1a;实现特定属性的public sette…

Evented PLEG: iSulad 稳态 CPU 利用率降低30%的关键特性

背景 容器技术在不断发展的过程中&#xff0c;已被广泛应用于多种场景。OpenAtom openEuler&#xff08;简称"openEuler"&#xff09; 社区容器引擎项目 iSulad[1]面向 CT、IT 领域的不同需求而生&#xff0c;它具有轻量级、高性能的特点&#xff0c;可以在资源受限…

高性能LDO电路设计,有配套文档

内容&#xff1a; 1、电路文件&#xff08;有仿真状态&#xff09;和PDK&#xff08;TSMC180&#xff09; 2、配套仿真结果文档讲解6页 3、参考资料三篇 指标&#xff1a; LDO 温度系数1.09ppm LDO 环路增益在 64.3dB&#xff0c;相位裕度在 66&#xff0c;系统稳定。 LDO 最大…

技术派Spring事件监听机制及原理

Spring事件监听机制是Spring框架中的一种重要技术&#xff0c;允许组件之间进行松耦合通信。通过使用事件监听机制&#xff0c;应用程序的各个组件可以在其他组件不直接引用的情况下&#xff0c;相互发送和接受消息。 需求 在技术派中有这样一个需求&#xff0c;当发布文章或…

ollama,springAi实现自然语言处理

ollama安装使用&#xff1a; https://ollama.com/ 下载速度比较慢的可以直接使用以下版本0.1.41 https://pan.baidu.com/s/1hCCkYvFjWqxvPyYA2-YElA?pwdotap 直接管理员身份双击安装&#xff0c;安装成功后会在任务栏里出现这个小图标&#xff1a; 打开cmd&#xff0c;输入…

WhatsApp:连接世界的即时通讯巨头

在数字化浪潮席卷全球的今天&#xff0c;即时通讯工具已成为人们日常生活中不可或缺的一部分。其中&#xff0c;WhatsApp凭借其卓越的功能、出色的用户体验和广泛的用户基础&#xff0c;在全球通讯领域崭露头角&#xff0c;成为连接世界的即时通讯巨头。今天将带您深入了解What…

tkinter显示图片

tkinter显示图片 效果代码解析打开和显示图像 代码 效果 代码解析 打开和显示图像 def open_image():file_path filedialog.askopenfilename(title"选择图片", filetypes(("PNG文件", "*.png"), ("JPEG文件", "*.jpg;*.jpeg&q…

数据资产赋能企业决策:通过精准的数据分析和洞察,构建高效的数据资产解决方案,为企业提供决策支持,助力企业实现精准营销、风险管理、产品创新等目标,提升企业竞争力

一、引言 在信息化和数字化飞速发展的今天&#xff0c;数据已成为企业最宝贵的资产之一。数据资产不仅包含了企业的基本信息&#xff0c;还蕴含了丰富的市场趋势、消费者行为和潜在商机。如何通过精准的数据分析和洞察&#xff0c;构建高效的数据资产解决方案&#xff0c;为企…

【论文通读】GUI Action Narrator: Where and When Did That Action Take

GUI Action Narrator: Where and When Did That Action Take 前言AbstractMotivationSolutionAct2CapData CollectionMetrics MethodExperimentAblation StudyVisual Prompt SizeSpatial PromptTemporal Prompt Conclusion 前言 一篇GUI操作benchmark的工作&#xff0c;作者提…

tkinter实现进度条

tkinter实现进度条 效果代码解析导入需要的模块定义进度条 代码 效果 代码解析 导入需要的模块 import tkinter as tk from tkinter import ttk定义进度条 def start_progress():progress[value] 0max_value 100step 10for i in range(0, max_value, step):progress[valu…

Win11找不到组策略编辑器(gpedit.msc)解决

由于需要同时连接有线网络和无线网络&#xff0c;且重启后双网络都自动连接&#xff0c;因此需要配置组策略。 但是win11找不到组策略编辑器。 灵感来源&#xff1a;Win11找不到组策略编辑器&#xff08;gpedit.msc&#xff09;解决教程 - 知乎 (zhihu.com) 在Win11中&#…

国网协议电表采集方案

项目背景及需求项目地点&#xff1a;重庆港西光伏电站&#xff08;中广核重庆&#xff09;项目背景&#xff1a;光伏发电并网项目电能监控项目目的及难点&#xff1a;实现对EDMI协议电表&#xff08;Mk6E&#xff09;的数据采集&#xff0c;监控光伏发电有效性&#xff0c;做到…

项目管理九大口诀

有工作一定有目标 有目标一定有任务 有任务一定有计划 有计划一定有执行 有执行一定有监控 有监控一定有调整 有调整一定有结果 有结果一定有责任 有责任一定有奖惩 &#x1fa77;有工作一定有目标 目标制定&#xff1a;SMART Specific&#xff08;具体性&#xff09;&#x…

# 职场生活之道:善于团结

在职场这个大舞台上&#xff0c;每个人都是演员&#xff0c;也是观众。要想在这个舞台上站稳脚跟&#xff0c;除了专业技能&#xff0c;更要学会如何与人相处&#xff0c;如何团结他人。团结&#xff0c;是职场生存的重要法则之一。 1. 主动团结&#xff1a;多一个朋友&#x…

《昇思25天学习打卡营第1天|基本介绍》

文章目录 前言&#xff1a;今日所学&#xff1a; 前言&#xff1a; 今天非常荣幸的收到了昇思25天学习打卡营的邀请。昇思MindSpore作为华为昇腾AI全栈的重要一员&#xff0c;他支持端、边、云独立的和协同的统一训练和推理框架&#xff0c;有着易于开发、执行效率高、全场景框…

Kotlin扩展函数(also apply run let)和with函数

also apply run let with的使用例子 private fun testOperator() {/*** also*/val person Person("ZhangSan", 18)person.also {// 通常仅仅打印使用, 也可以通过it修改it.name "ZhangSan1"println("also inner name: " it.name)}println(&qu…

Redis-分布式锁(基本原理和不同实现方式对比)

文章目录 1、基本原理2、不同实现方式 1、基本原理 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁&#xff0c;只要大家使用的是同一把锁&#xff0c;那么我们就能锁住线程&#xff0c;不让线程进行&am…

Firewalld 概述

1.firewalld简介 firewalld的作用是为包过滤机制提供匹配规则(或称为策略),通过各种不同的规则&#xff0c;告诉 netfiter对来自指定源、前往指定目的或具有某些协议特征的数据包采取何种处理方式。 为了更加方便地组织和管理防火墙&#xff0c;firewalld 提供了支持网络区域…

以太网基础知识

文章目录 一、以太网&#xff08;Ethernet&#xff09;介绍二、协议介绍三、什么是PHY&#xff1f;1.标准接口协议&#xff1a;2.寄存器配置&#xff1a;3.自动协商&#xff1a; 四、时序4.1RGMII接口时序4.1.1 对其模式4.1.2 延时模式&#xff08;常用&#xff09; 4.2MDIO接口…