用队列实现栈——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.mfbz.cn/a/592849.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

支付宝支付流程

第一步前端:点击去结算,前端将商品的信息传递给后端,后端返回一个商品的订单号给到前端,前端将商品的订单号进行存储。 对应的前端代码:然后再跳转到支付页面 // 第一步 点击去结算 然后生成一个订单号 // 将选中的商…

SQL 基础 | AVG 函数的用法

在SQL中,AVG()是一个聚合函数,用来计算某个列中所有值的平均值。 它通常与GROUP BY子句一起使用,以便对分组后的数据进行平均值计算。 AVG()函数在需要了解数据集中某个数值列的中心趋势时非常有用。 以下是AVG()函数的一些常见用法&#xff…

DETR类型检测网络实验2---优化测试

补全reference_point Anchor-DETR提出用预定义的参考点生成query_pos; DBA-DETR提出预定义参考信息由(x,y)增至(x,y,w,h) 那么在3D检测任务中是否可以把预定义参考信息补全为(x,y,z,l,w,h,sint,cost),而query_pos都是使用xy两个维度(因为是bev网络). (这种方法在Sparse-DETR中…

CMakeLists.txt语法规则:部分常用命令说明一

一. 简介 前一篇文章简单介绍了CMakeLists.txt 简单的语法。文章如下: CMakeLists.txt 简单的语法介绍-CSDN博客 接下来对 CMakeLists.txt语法规则进行具体的学习。本文具体学习 CMakeLists.txt语法规则中常用的命令。 二. CMakeLists.txt语法规则:…

探索LLM在广告领域的应用——大语言模型的新商业模式和新个性化广告的潜力

概述 在网络搜索引擎的领域中,广告不仅仅是一个补充元素,而是构成了数字体验的核心部分。随着互联网经济的蓬勃发展,广告市场的规模已经达到了数万亿美元,并且还在持续扩张。广告的经济价值不断上升,它已经成为支撑大…

C++初阶之模板初阶

一、泛型编程 如何实现一个通用的交换函数呢? void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, double& right) {double temp left;left right;right temp; } void Swap(char& left,…

spring boot3多模块项目工程搭建-上(团队开发模板)

⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 目录 写在前面 多模块结构优缺点 模块介绍 Common 模块: API 模块: Web 模块: Service 模块: DAO 模块: 搭建步骤 1.创建 父…

JavaWeb_请求响应_简单参数实体参数

一、SpringBoot方式接收携带简单参数的请求 简单参数:参数名与形参变量名相同,定义形参即可接收参数。并且在接收过程中,会进行自动的类型转换。 启动应用程序后,在postman中进行测试: 请求成功,响应回了O…

Flask教程3:jinja2模板引擎

文章目录 模板的导入与使用 模板的导入与使用 Flask通过render_template来实现模板的渲染,要使用这个方法,我们需要导入from flask import rander_template,模板中注释需放在{# #}中 模板的第一个参数为指定的模板文件名称,如自定…

微信小程序生成二维码加密(CryptoJS4.0加密PHP8.0解密)AES方式加密

1、小程序创建 crypto-js.js和crypto.js两个文件(点击文件即可) 2、小程序js页面引入 var crypto require(../../utils/crypto.js);//注意路径是否正确3、使用 let data {id: that.data.id,name: dx}console.log(JSON.stringify(data))console.log(&…

【论文阅读】Learning Texture Transformer Network for Image Super-Resolution

Learning Texture Transformer Network for Image Super-Resolution 论文地址Abstract1. 简介2.相关工作2.1单图像超分辨率2.2 Reference-based Image Super-Resolution 3. 方法3.1. Texture TransformerLearnable Texture Extractor 可学习的纹理提取器。Relevance Embedding.…

【八股】AQS,ReentrantLock实现原理

AQS 概念 AQS 的全称是 AbstractQueuedSynchronized (抽象队列同步器),在java.util.concurrent.locks包下面。 AQS是一个抽象类,主要用来构建锁和同步器,比如ReentrantLock, Semaphore, CountDownLatch,里…

Leetcode—163. 缺失的区间【简单】Plus

2024每日刷题&#xff08;126&#xff09; Leetcode—163. 缺失的区间 实现代码 class Solution { public:vector<vector<int>> findMissingRanges(vector<int>& nums, int lower, int upper) {int n nums.size();vector<vector<int>> an…

基于遗传优化模糊控制器的水箱水位控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 模糊控制器原理 4.2 遗传算法原理 4.3 遗传优化模糊控制器的工作流程 5.完整工程文件 1.课题概述 基于遗传优化模糊控制器的水箱水位控制系统simulink建模与仿真。对比模糊控制器和基于遗传优化的…

Python基础详解一

一&#xff0c;print打印 print("hello word") print(hello word) 双引号和单引号都可以 二&#xff0c;数据类型 Python中常用的有6种值的类型 输出类型信息 print(type(11)) print(type("22")) print(type(22.2)) <class int> <class str&…

飞书API(7):MySQL 入库通用版本

一、引入 在上一篇介绍了如何使用 pandas 处理飞书接口返回的数据&#xff0c;并将处理好的数据入库。最终的代码拓展性太差&#xff0c;本篇来探讨下如何使得上一篇的最终代码拓展性更好&#xff01;为什么上一篇的代码拓展性太差呢&#xff1f;我总结了几点&#xff1a; 列…

深入理解 Java 并发:AbstractQueuedSynchronizer 源码分析

序言 在多线程编程中&#xff0c;同步机制是保障线程安全和协调线程之间操作顺序的重要手段。AQS 作为 Java 中同步机制的基础框架&#xff0c;为开发者提供了一个灵活且高效的同步工具。本文将通过对 AQS 源码的分析&#xff0c;解读 AQS 的核心实现原理&#xff0c;并深入探…

wireshark的安装使用及相关UDP、TCP、 ARP

初步了解&#xff1a; 进入wireshark后如图&#xff1a; 从图中可以看到很多网络连接在操作的时候我们需要监测哪些 我们可以直接在本地的运行框中输入ipconfig来查看 如图&#xff1a; 从以上图片中我们可以清楚地看到哪些网络连接已经连接的我们只需要按需监测他们即可 但…

【LinuxC语言】信号集与sigprocmask

文章目录 前言一、信号集1.1 操作信号集相关的函数1.2 信号屏蔽字1.3 sigprocmask1.4 示例代码 总结 前言 在Linux C编程中&#xff0c;信号是一种重要的进程间通信机制&#xff0c;用于通知进程发生了特定的事件。然而&#xff0c;程序在执行过程中可能会收到各种各样的信号&…

银河麒麟桌面版开机后网络无法自动链接 麒麟系统开机没有连接ens33

1.每次虚拟机开机启动麒麟操作系统&#xff0c;都要输入账号&#xff0c;密码。 进入点击这个ens33 内网才连接 2. 如何开机就脸上呢&#xff1f; 2.1. 进入 cd /etc/sysconfig/network-scripts 2.2 修改参数 onbootyes 改为yes 2.3 重启即可 a. 直接重启机器查看是否正常&…
最新文章