用队列实现栈——leetcode刷题

        题目的要求是用两个队列实现栈,首先我们要考虑队列的特点:先入先出,栈的特点:后入先出,所以我们的目标就是如何让先入栈的成员后出栈,后入栈的成员先出栈。

        因为有两个队列,于是我们可以这样想:让 队列1 的成员除最后一个成员出队列到 队列2,这时 队列1 剩下的成员不就是要出栈的成员吗?(即后入先出)那么我们如何控制让 队列1 出队列到只剩下一个成员呢?我们可以使用size函数,即 size(队列1) 是1的时候再Pop或者Peek,就是出栈。如图所示:


        我没有提到入栈,入栈其实就是把数据按照顺序放进 队列1 中,因为队列和栈在存储数据方面都是顺序存放的,只有在出数据的时候顺序不同,这里的 队列1 就可以理解为栈的拷贝,队列2 就可以理解为出栈的工具,因为只有在出栈时才会占用 队列2 。

        Pop完或者Peek查看完并没有结束,我们要把 队列2 中的成员再归还到 队列1 中,如果是Pop(出栈函数,删除栈顶数据),那么 队列2 直接出队列到 队列1 即可,如果是Peek(查看栈顶数据,不删除),那么 队列1 中的成员要先出队列到 队列2 在执行出队列到 队列1 的操作,如图:

接下来是代码实现,

首先还是创建栈结构体和结构体中的两个队列:


struct QueueList {int val;struct QueueList* next;
};
struct Queue {struct QueueList* head;struct QueueList* tail;
};
typedef struct {struct Queue* q1;struct Queue* q2;
} MyStack;MyStack* myStackCreate() {MyStack* stack=(MyStack*)malloc(sizeof(MyStack));stack->q1=(struct Queue*)malloc(sizeof(struct Queue));stack->q2=(struct Queue*)malloc(sizeof(struct Queue));QueueInit(stack->q1);QueueInit(stack->q2);return stack;
}

        主要是最后两块代码,创建栈结构体并且为栈申请空间。这里我一开始犯了一个错误,没有给每个队列的指针申请空间,导致q1和q2是野指针,所以也提醒了我一次malloc是为两个指针存放开辟空间, 但并没有为指针指向的位置开辟空间,导致野指针的问题。所以要二次malloc为队列指针开辟空间。

接着是入栈函数:

void myStackPush(MyStack* obj, int x) {QueuePushBack(obj->q1,x);
}

        直接就是把数据放进 队列1 q1中去。

然后是Pop(出栈函数,删除栈顶)和Peek(查看栈顶成员函数):

int myStackPop(MyStack* obj) {while(Queue_size(obj->q1)>1){QueuePushBack(obj->q2,QueueFrontPop(obj->q1));}int val=QueueFrontPop(obj->q1);while(Queue_size(obj->q2)>0){QueuePushBack(obj->q1,QueueFrontPop(obj->q2));}return val;
}int myStackTop(MyStack* obj) {while(Queue_size(obj->q1)>1){QueuePushBack(obj->q2,QueueFrontPop(obj->q1));}int val=QueueFrontPop(obj->q1);QueuePushBack(obj->q2,val);while(Queue_size(obj->q2)>0){QueuePushBack(obj->q1,QueueFrontPop(obj->q2));}return val;
}

        每个函数中都有两个while循环,第一个是将 队列1 q1 的成员拷贝到 队列2 q2 ,第二个是将 队列2 q2 的成员拷贝到 队列1 q1。
        先解释一下Pop函数,根据刚才的流程图,当size>1时,就是说只有一个成员时停止拷贝,这时把最后的值Pop掉并记录,然后当size>0时,就是说把 q2 的成员全部拷贝回 q1,然后返回Pop掉的值。
        Peek函数只改变了一点,就是Pop改为Peek,记录下栈顶成员,然后接着把 q1 拷贝回 q2,再整个队列拷贝回 q2。

最后是检查是否为空 Is_empty 函数和销毁内存函数:

bool myStackEmpty(MyStack* obj) {if(Queue_size(obj->q1)==0){return true;}else{return false;}
}void myStackFree(MyStack* obj) {QueueDes(obj->q1);QueueDes(obj->q2);free(obj);
}

        因为每次调用函数过后 队列1 q1 就相当于栈,所以只需要检查 队列1 是否为空即可。

这就是文章的全部内容了,希望对你有所帮助,如有错误欢迎评论。

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

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

相关文章

vue3(实现上下无限来往滚动)

一、问题描述 一般在大屏项目中,很常见的效果,就是容器中的内容缓慢地向下移动,直到底部停止,然后快速滚动回顶部,然后接着缓慢滚动到底部。并且在特定的情况下,还需要进行一些小交互,那就还得让…

Leetcode——面试题02.04.分割链表

面试题 02.04. 分割链表 - 力扣(LeetCode) 对于该链表OJ,我们两种大的方向: 1.在原链表上修改;2.创建新链表,遍历原链表。 在原链上进行修改:如果该节点的val小于x则继续往后走,如…

2.3Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3-基础-Vue进阶

Vue方法、计算属性及监听器 在vue中处理复杂的逻辑的时候,我们经常使用计算属性、方法及监听器。 methods:方法:它们是挂载在Vue对象上的函数,通常用于做事件处理函数,或自己封装的自定义函数。 computed&#xff1…

Ubuntu服务器创建新用户及解决新用户登录Access denied问题

目录 Ubuntu服务器创建新用户及解决新用户登录Access denied问题创建账号步骤创建用户只创建用户添加用户到sudo组 允许账号远程连接重启ssh服务 删除账号要删除用户而不删除用户文件如果要删除并且删除用户的家目录和邮件 查询指令查看所有用户查询特定用户账户信息查看用户组…

Java中面向对象三大特征(封装、继承、多态)

目录 一、封装 1.1 封装的意义 1.2 如何进行封装 二、继承 2.1 继承的意义 2.2 如何继承 2.3 继承的优点 2.4 继承的缺点 三、多态 3.1 多态的定义 3.2 多态的使用要求 一、封装 所谓封装就是将对象的属性隐藏起来,不让外界直接访问,而是通过…

【Micropython Pitaya Lite教程】key按键与EXTI中断

文章目录 前言一、按键的使用1.1 按键的简介1.2 读取按键的高低电平 二、EXIT外部中断2.1 EXIT外部中断简介2.2 外部中断基础知识2.3 设置外部中断2.4 示例代码 总结 前言 Micropython Pitaya Lite开发板提供了丰富的功能和灵活的扩展性,其中包括了按键&#xff08…

Python 全栈系列241 GFGo Lite迭代

说明 随着整个算网开发逐渐深入,各个组件、微服务的数量、深度在不断增加。由于算网是个人项目,我一直按照MVP(Minimum Viable Product )的原则在推进。由于最初的时候对架构、算法和业务的理解并没有那么深刻,所以MVP的内容还是在不断变化&…

精准医疗中的图像识别技术:从诊断到治疗的新变革

在精准医疗中,图像识别技术的应用正在从诊断到治疗带来一场新的变革。这种技术通过深度学习和计算机视觉算法,能够分析和解释医学图像,如X射线、CT扫描、MRI等,从而帮助医生更准确地诊断疾病,制定更个性化的治疗方案。…

IoTDB 入门教程 基础篇①——时序数据库为什么选IoTDB ?

文章目录 一、前文二、性能排行第一三、完全开源四、数据文件TsFile五、乱序数据高写入六、其他七、参考 一、前文 IoTDB入门教程——导读 关注博主的同学都知道,博主在物联网领域深耕多年。 时序数据库,博主已经用过很多,从最早的InfluxDB&a…

跟我学C++中级篇——const和constexpr的使用

一、从例程介绍 已经不同的篇章里介绍和分析过const及constexpr&#xff0c;特别对于后者&#xff0c;从c11到c14直到c17甚至以后&#xff0c;功能都不断的在完善。那么这么多复杂的应用如何搞清楚呢&#xff1f;下面先从代码看起&#xff1a; #include <iostream>void…

Linux基础之yum和vim

目录 一、软件包管理器yum 1.1 软件包的概念 1.2 软件包的查看 1.3 软件包的安装和删除 二、Linux编辑器之vim 2.1 vim的基本概念 2.2 正常模式&#xff08;命令模式&#xff09; 2.3 底行模式 2.4 输入模式 2.5 替换模式 2.6 视图模式 2.7 总结 一、软件包管理器yu…

MATLAB可视化图形绘制详解

图形常见的修饰命令 ①曲线修饰 曲线修饰包括曲线的顔色、线型和标示符号的设置。曲线修饰的命令格式如下。 plot(x,y,option):option定义了曲线的颜色、线型和标示符号。 MATLAB曲线修饰的各种选项见表 举例&#xff1a; x-2*pi:pi/50:2*pi; y1x.^2;y2cos(2*X);y3y1.*y2…

ctfshow web入门 php反序列化 web254--web259

web 254 只要传入的值与其类中的值相等即为true就有flag usernamexxxxxx&passwordxxxxxx web255 序列化和反序列化就像是把物品放进盒子和从盒子里取出物品的过程一样&#xff0c;只是在计算机编程中&#xff0c;我们是针对数据进行的操作。 这一题就是要把cookie进行序…

【Python项目】基于DJANGO的【基于语音识别的智能垃圾分类系统】

技术简介&#xff1a;使用Python技术、DJANGO框架、MYSQL数据库等实现。 系统简介&#xff1a;用户们可以在系统上面录入自己的个人信息&#xff0c;录入后还可以对信息进行修改&#xff0c;网站可以对用户上传的音频文件进行识别&#xff0c;然后进行垃圾分类。 背景&#xf…

【竞技宝jjb.lol】LOL:TES顺利晋级却暴露问题

北京时间2024年5月5日,英雄联盟2024MSI季中赛正在如火如荼的进行之中,目前入围赛阶段的比赛已经进入尾声,入围赛实力最强的两支战队T1、TES都已经顺利晋级淘汰赛阶段,在昨天的比赛结束之后,A组的FLY、PSG,B组的FNC、GAM将争夺剩下的两个出线名额。 回顾这次入围赛中,T1和TES的比…

课题学习(二十三)---三轴MEMS加速度计芯片ADXL372

声明&#xff1a;本人水平有限&#xff0c;博客可能存在部分错误的地方&#xff0c;请广大读者谅解并向本人反馈错误。 一、基础配置 测量范围-200g-200g&#xff0c;分辨率为12位&#xff0c; V s 、 V D D I / O V_s、V_{DDI/O} Vs​、VDDI/O​范围为1.6V-3.5V 1.1 引脚配…

第20天 多线程

多线程 cpu一次只能处理一条指令&#xff0c;所谓同时是因为人反应不过来 分为多个时间片段&#xff0c;尽可能平均分配给每一个线程 线程的创建 &#xff1a; 第1种方法&#xff1a;继承thread并重写run方法 psvm{ Thread t1 new MyThread1(); Thread t2 new MyThread2()…

u盘格式化后电脑读不出来怎么办?u盘格式化的东西还能恢复吗

随着科技的快速发展&#xff0c;U盘已成为我们日常生活和工作中不可或缺的数据存储工具。然而&#xff0c;有时我们可能会遇到U盘格式化后电脑无法读取的情况&#xff0c;或是误格式化导致重要数据丢失。面对这些问题&#xff0c;我们该如何应对&#xff1f;本文将为您详细解答…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之七 简单进行人脸检测并添加面具特效实现

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之七 简单进行人脸检测并添加面具特效实现 目录

RISC-V异常处理相关内容

异常处理相关内容 异常处理相关内容异常处理准备工作异常处理函数Opensbi系统调用的注册异常处理相关内容 异常处理准备工作 这里需要特殊强调的是异常处理构建的相关内容: 这里会将a4寄存器中的值存储到CSR_MTVEC这个状态寄存器,也就是异常处理程序的的入口;如果遇到异常…