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

用队列实现栈
题目解读

在这里插入图片描述
本题的要求是要用两个队列来实现一个先进后出的栈,并且要有以下功能:
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.hqwc.cn/news/222814.html

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

相关文章

C语言打印九九乘法表的多种方式多种形式(完整,左上,左下,右上,右下)

📢博客主页:肩匣与橘📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢本文由肩匣与橘编写,首发于CSDN🙉📢生活依旧是美好而又温柔的,你也是✨ …

CodeWhisperer——一个十分强大的工具

使用心得: Amazon CodeWhisperer 是亚⻢逊出品的一款基于机器学习的 AI 编程助手,可实时提供代码建议。现在已正式可用,面向个人提供免费服务,通过在各种流行的 IDE 里集成 CodeWhisperer(包括我们常用的 JetBrains 产…

AIGC 创业公司还没盈利,微软、Adobe 已赚得盆满钵满

一出奥特曼在 OpenAI「来去之间」的戏码,以回归暂告一段落。 过程很抓马,吃瓜群众很激动,当然了,最开心的还得是微软。 不仅因为这出「闹剧」无论怎么发展,都是微软稳赢,还因为背后潜藏着一个更大的瓜—— …

UniPro集成华为云WeLink 为企业客户构建互为联接的协作平台

华为云WeLink是华为开启数字化办公体验、帮助企业实现数字化转型的实践,类似钉钉。UniPro的客户企业中,有使用WeLink作为协作工具的,基于客户的实际业务需求,UniPro实现了与WeLink集成的能力,以帮助客户企业丰富和扩展…

尝试访问启动磁盘设置时出错怎么办?保姆级教程!

用户案例:尝试访问启动磁盘设置时出错 “由于专业所需软件仅支持Windows系统,我决定在我的MAC电脑上安装Windows 10双系统。然而,安装完成后遇到了问题。Boot Camp打开时报错:“尝试访问启动磁盘设置时出错”,同时…

线上问题整理-ConcurrentModificationException异常

项目场景: 商品改价:商品改价中通过多线程批量处理经过 Lists.partition拆分的集合对象 问题描述 商品改价中通过多线程批量处理经过 Lists.partition拆分的集合对象,发现偶尔会报 java.util.ConcurrentModificationException: nullat jav…

Maven生命周期

Maven生命周期 通过IDEA工具的辅助,能很轻易看见Maven的九种生命周期命令,如下: 双击其中任何一个,都会执行相应的Maven构建动作,为啥IDEA能实现这个功能呢?道理很简单,因为IDEA封装了Maven提供…

IDEA中Tomcat启动web项目

1.首先【Run】-->【Edit Configurations】,进入对应功能界面 2.点击左上角【】,选择Tomcat Server -->Local 3.Name输入自己中意的,下面两个port,保证没被占用就行 4.切到【Deployment】页签,点击【】&#xff…

力扣373场周赛题解

第一题: 这个题是一个简单题,数据范围也特别小,所以直接使用模拟方式暴力解答。 直接进行行移动的过程,然后检查移动后的结果是否与移动前相同。 代码: ​ public class Solution {// 将指定行循环右移k次pri…

Python代码实现购买打折衣服,并且flask框架在web浏览器上输入购买件数,自动计算出价格

2.某商店T恤的价格为35元/件(2件9折,3件以上8折),裤子的价格为120 元/条(2条以上9折). 小明在该店买了3件T恤和2条裤子,请计算并显示小明应该付多少钱? #yifu.py from flask import Flask,render_template,request##…

VM安装Centos

文章目录 第2章 VM与Linux的安装2.1 VMWare安装2.2 CentOS安装 第3章 Linux文件与目录结构3.1 Linux文件3.2 Linux目录结构 第4章 VI/VIM编辑器4.1 是什么4.2 测试数据准备4.3 一般模式4.4 编辑模式4.5 命令模式4.6 模式间转换 第5章 网络配置和系统管理操作5.1 查看网络IP和网…

Java核心知识点整理大全18-笔记

Java核心知识点整理大全-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全2-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全3-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全4-笔记-CSDN博客 Java核心知识点整理大全5-笔记-CSDN博客 Java核心知识点整理大全6…