用队列和栈分别实现栈和队列

news2024/11/27 7:41:19
用队列实现栈
题目解读

在这里插入图片描述
本题的要求是要用两个队列来实现一个先进后出的栈,并且要有以下功能:
1.将元素压入栈中
2.移除栈顶元素并且返回他
3.返回栈顶元素
4.判断栈是否为空

题目构思和代码实现

我们首先要做的就是将实现队列的代码导入该题(也可以自己写)
下面我们来进行题目的构思:
我们知道,栈的增加和删除元素都是从栈顶进行操作的,并且遵循先进后后出的原则,但是队列是遵循先进先出的规则,增加元素从队尾增加,删除元素从队首删除。
怎么解决呢?
其实题目已经给了我们提示:用两个队列!
我们可以这样,先构造两个队列,一个用来删除栈的元素,一个用来增加栈的元素。
所以我们就可以开辟两个队列,一个叫pop,一个叫push

typedef struct 
{
    Queue push;
    Queue pop;
} MyStack;

MyStack* myStackCreate() 
{
    MyStack* obj=(MyStack*)malloc(sizeof(MyStack));
    if(obj==NULL)
    {
        return NULL;
    }
    QueueInit(&obj->push);
    QueueInit(&obj->pop);
    return obj;
}

我们需要将元素压入栈中是就看哪一个队列不为空就压入到那个队列中
我们用之前队列写的判断队列 是否为空来增加代码的可读性

void myStackPush(MyStack* obj, int x) 
{
    if(!QueueEmpty(&obj->push))
    {
        QueuePush(&obj->push,x);
    }
    else
    {
        QueuePush(&obj->pop,x);
    }
}

移除栈中的元素就要看情况了:
我们首先假设push队列为空,pop队列不为空,然后再用一个if语句进行判断,如果push不为空就交换
然后我们将不为空的那个队列里面的除了队尾元素的所有元素都统统放入为空的那个队列里面,知道不为空队列里面只剩下一个元素,先存储这个元素,然后就直接将他删除,最后返回这个元素
在这里插入图片描述

int myStackPop(MyStack* obj) 
{
    Queue* empty=&obj->push;
    Queue* nonempty=&obj->pop;
    if(!QueueEmpty(&obj->push))
    {
        empty=&obj->pop;
        nonempty=&obj->push;
    }
    while(QueueSize(nonempty)>1)
    {
        QueuePush(empty,QueueFront(nonempty));
        QueuePop(nonempty);
    }
    int top=QueueFront(nonempty);
    QueuePop(nonempty);
    return top;
}

返回栈顶元素就直接返回非空队列的队尾元素即可

nt myStackTop(MyStack* obj) 
{
    if(!QueueEmpty(&obj->push))
    {
        return QueueBack(&obj->push);
    }
    else
    {
        return QueueBack(&obj->pop);
    }
}

栈为空时两个队列都为空

bool myStackEmpty(MyStack* obj) 
{
    return QueueEmpty(&obj->pop)&&QueueEmpty(&obj->push);
}

完整代码如下:

typedef struct 
{
    Queue push;
    Queue pop;
} MyStack;


MyStack* myStackCreate() 
{
    MyStack* obj=(MyStack*)malloc(sizeof(MyStack));
    if(obj==NULL)
    {
        return NULL;
    }
    QueueInit(&obj->push);
    QueueInit(&obj->pop);
    return obj;
}

void myStackPush(MyStack* obj, int x) 
{
    if(!QueueEmpty(&obj->push))
    {
        QueuePush(&obj->push,x);
    }
    else
    {
        QueuePush(&obj->pop,x);
    }
}

int myStackPop(MyStack* obj) 
{
    Queue* empty=&obj->push;
    Queue* nonempty=&obj->pop;
    if(!QueueEmpty(&obj->push))
    {
        empty=&obj->pop;
        nonempty=&obj->push;
    }
    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->push))
    {
        return QueueBack(&obj->push);
    }
    else
    {
        return QueueBack(&obj->pop);
    }
}

bool myStackEmpty(MyStack* obj) 
{
    return QueueEmpty(&obj->pop)&&QueueEmpty(&obj->push);
}
用栈实现队列
题目解读

在这里插入图片描述
题目的意思和上一题大同小异,要实现的功能都大差不差的,这里我就不做过多的解读,直接开始构思:

题目构思和代码实现

要想实现队列,我们用两个栈如何实现呢?
首先,栈时遵循先进后出的原则,但是队列时先进先出,难不成也像上一题一样,一个栈用来增加数据,另一个栈用来删除数据?

typedef struct 
{
    Stack pushstack;
    Stack popstack;
} MyQueue;

MyQueue* myQueueCreate() 
{
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    if(obj==NULL)
    {
        perror("malloc");
        return NULL;
    }
    StackInit(&obj->pushstack);
    StackInit(&obj->popstack);
    return obj;
}

其实我们可以这样:
当你要增加元素,就将这个元素压入pushstack也就是专门存储增加队列的增加的元素的
删除元素时就有点麻烦咯
当需要删除时,我们要删除的是最先进入队列的元素,也就是pushstack的栈底元素,那么如何将他删除呢?
我们可以将pushstack的栈顶元素逐个压入到popstack中,然后删除掉pushstack中的栈底元素即可
这里题目中的查找队首元素也可以搭配使用,当pop栈为空时,队首元素就是push栈的栈底元素,pop栈不为空时,就是pop栈的栈顶元素

int myQueuePeek(MyQueue* obj) 
{
    if(StackEmpty(&obj->popstack))
    {
        while(!StackEmpty(&obj->pushstack))
        {
            StackPush(&obj->popstack,StackTop(&obj->pushstack));
            StackPop(&obj->pushstack);
        }
    }
    return StackTop(&obj->popstack);
}

在这里插入图片描述
增加和删除元素代码如下:

void myQueuePush(MyQueue* obj, int x) 
{
    StackPush(&obj->pushstack,x);
}

int myQueuePop(MyQueue* obj) 
{
    int front=myQueuePeek(obj);
    StackPop(&obj->popstack);
    return front;
}

队列的销毁要注意,free掉obj的同时要记得销毁两个栈:

void myQueueFree(MyQueue* obj) 
{
    StackDestroy(&obj->popstack);
    StackDestroy(&obj->pushstack);
    free(obj);
}

完整代码如下:

typedef struct 
{
    Stack pushstack;
    Stack popstack;
} MyQueue;


MyQueue* myQueueCreate() 
{
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    if(obj==NULL)
    {
        perror("malloc");
        return NULL;
    }
    StackInit(&obj->pushstack);
    StackInit(&obj->popstack);
    return obj;
}

bool myQueueEmpty(MyQueue* obj) 
{
    return StackEmpty(&obj->popstack)&&StackEmpty(&obj->pushstack);
}

void myQueuePush(MyQueue* obj, int x) 
{
    StackPush(&obj->pushstack,x);
}

int myQueuePeek(MyQueue* obj) 
{
    if(StackEmpty(&obj->popstack))
    {
        while(!StackEmpty(&obj->pushstack))
        {
            StackPush(&obj->popstack,StackTop(&obj->pushstack));
            StackPop(&obj->pushstack);
        }
    }
    return StackTop(&obj->popstack);
}

int myQueuePop(MyQueue* obj) 
{
    int front=myQueuePeek(obj);
    StackPop(&obj->popstack);
    return front;
}

void myQueueFree(MyQueue* obj) 
{
    StackDestroy(&obj->popstack);
    StackDestroy(&obj->pushstack);
    free(obj);
}

好了,今天的分享到这里就结束了,谢谢大家的支持!

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

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

相关文章

【深度学习】如何找到最优学习率

经过了大量炼丹的同学都知道,超参数是一个非常玄乎的东西,比如batch size,学习率等,这些东西的设定并没有什么规律和原因,论文中设定的超参数一般都是靠经验决定的。但是超参数往往又特别重要,比如学习率&a…

扩散模型实战(十二):使用调度器DDIM反转来优化图像编辑

推荐阅读列表: 扩散模型实战(一):基本原理介绍 扩散模型实战(二):扩散模型的发展 扩散模型实战(三):扩散模型的应用 扩散模型实战(四&#xff…

python之pyqt专栏4-代码控制部件

通过前面的学习,我们已经回创建新的pyqt项目、对项目结构有了了解、也了解Qt Designer设计UI界面并 把"xx.ui"转换为“xxx.py”。 pyqt模块与类 pyqt6 由模块组成,而模块里面又有很多的类 在pyqt官网Modules — PyQt Documentation v6.6.0页面…

函数的防抖与节流

一、函数防抖 (一)防抖的理解 防抖就是将所有的触发都取消,在规定的时间结束过后才会执行最后一次,也就是说连续快速的触发只会执行最后一次结果。 也可以理解为游戏里的回城按钮,每点一下就会重新刷新回城进度&…

SSM 框架整合

1 整合配置 1.1 流程 1.2 Spring 整合 MyBatis 1.3 Spring 整合 SpringMVC 1.4 配置代码 JdbcConfig.java public class JdbcConfig {Value("${jdbc.driver}")private String driver;Value("${jdbc.url}")private String url;Value("${jdbc.usern…

【挑战业余一周拿证】CSDN官方课程目录

一、亚马逊云科技简介 二、在云中计算 三、全球基础设施和可靠性 四、联网 五、存储和数据库 六、安全性 七、监控和分析 八、定价和支持 九、迁移和创新 十、云之旅 关注订阅号 CSDN 官方中文视频(免费):点击进入 一、亚马逊云科…

Apache POI(处理Miscrosoft Office各种文件格式)

文章目录 一、Apache POI介绍二、应用场景三、使用步骤1.导入maven坐标2.写入代码讲解3.读取代码讲解 总结 一、Apache POI介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用 POI 在 Java 程序中对Miscrosoft Office…

N7 LUP.2.3 DRC如何解决?

这个问题在Design Rule中的介绍如下图: 解决办法是od 15 um的范围要加LUP_GR* cell,需要提高密度(加的位置需要符合tcic)去fix。

ubuntu 安装 jetbrains-toolbox

ubuntu 安装 jetbrains-toolbox 官网下载 jetbrains-toolbox jetbrains 官网 jetbrains 官网:https://www.jetbrains.com/ jetbrains-toolbox 官网下载页面 在下载页面点击 Download 安装 jetbrains-toolbox 解压 jetbrains-toolbox 安装包 到指定目录 本案例将…

【Dockerfile】将自己的项目构建成镜像部署运行

目录 1.Dockerfile 2.镜像结构 3.Dockerfile语法 4.构建Java项目 5.基于Java8构建项目 1.Dockerfile 常见的镜像在DockerHub就能找到,但是我们自己写的项目就必须自己构建镜像了。 而要自定义镜像,就必须先了解镜像的结构才行。 2.镜像结构 镜…

Python——常见内置模块

Python 模块(Modules)1、概念模块函数类变量2、分类3、模块导入的方法:五种4、使用import 导入模块5、使用from……import部分导入6、使用as关键字为导入模块或功能命名别名7、模块的搜索目录8、自定义模块 常见内置模块一、math模块二、rand…

[pyqt5]PyQt5之如何设置QWidget窗口背景图片问题

目录 PyQt5设置QWidget窗口背景图片 QWidget 添加背景图片问题QSS 背景图样式区别PyQt设置窗口背景图像,以及图像自适应窗口大小变化 总结 PyQt5设置QWidget窗口背景图片 QWidget 添加背景图片问题 QWidget 创建的窗口有时并不能直接用 setStyleSheet 设置窗口部分…

手机技巧:安卓微信8.0.44测试版功能介绍

目录 一、更新介绍 二、功能更新介绍 拍一拍撤回功能 聊天设置界面文案优化 关怀模式新增了非常实用的安静模式 微信设置中新增翻译设置选项 近期腾讯官方终于发布了安卓微信8.0.44测试版,今天小编继续给大家介绍一个本次安卓微信8.0.44测试版本更新的内容&am…

网络运维与网络安全 学习笔记2023.11.26

网络运维与网络安全 学习笔记 第二十七天 今日目标 NAT场景与原理、静态NAT、动态NAT PAT原理与配置、动态PAT之EasyIP、静态PAT之NAT Server NAT场景与原理 项目背景 为节省IP地址和费用,企业内网使用的都是“私有IP地址” Internet网络的组成设备&#xff0c…

3 时间序列预测入门:TCN

0 引言 TCN(全称Temporal Convolutional Network),时序卷积网络,是在2018年提出的一个卷积模型,但是可以用来处理时间序列。 论文:https://arxiv.org/pdf/1803.01271.pdf 一维卷积:在时间步长方…

轻量应用服务器推荐,入门首选

轻量应用服务器: 配置高,价格低,高性价比,已经成为开发者和中小企业首选服务器。 轻量-爆款 腾讯云轻量应用服务器 2核2G 3M带宽 40G SSD盘 月流量200G 一月45元。 推荐理由: 腾讯云这次活动预备了多款轻量应用服务器。如果做小…

【Java基础系列】文件上传功能

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

BUUCTF刷题之路-web-[GXYCTF2019]Ping Ping Ping1

启动环境后,是一个简简单单的页面: 看样子是能够触发远程执行漏洞的。尝试下ping 127.0.0.1,如果有回显说明我们的想法是对的。 最近才学习的nc反弹shell。想着是否能用nc反弹shell的办法。控制服务器然后输出flag呢?于是我测试下…

女生儿童房装修:原木上下铺搭配粉色调。福州中宅装饰,福州装修

你是否正在为女生儿童房的装修而发愁呢?该如何让房间既适合孩子生活,又能够满足日常学习的需要呢?这里有一个精美的装修案例,或许能够为你提供一些灵感。 1️⃣ 原木上下铺 房间的上下铺采用了原木色调,带来了自然、温…

RT-DETR 更换损失函数之 SIoU / EIoU / WIoU / Focal_xIoU

文章目录 更换方式CIoUDIoUEIoUGIoUSIoUWIoUFocal_CIoUFocal_DIoUFocal_EIoUFocal_GIoUFocal_SIoU提示更换方式 第一步:将ultralytics/ultralytics/utils/metrics.py文件中的bbox_iou替换为如下的代码:class