当前位置: 首页 > news >正文

Java 栈和队列的交互实现

文章目录

  • 队列和栈的区别
  • 一.用队列模拟实现栈
    • 1.1入栈
    • 1.2出栈
    • 1.3返回栈顶元素
    • 1.4判断栈是否为空
  • 二.用栈模拟实现队列
    • 2.1 入队
    • 2.2出队
    • 2.3peek
    • 2.4判断队列是否为空
  • 三.完整代码
    • 3.1 队列模拟实现栈
    • 3.2栈模拟实现队列


队列和栈的区别

栈和队列都是常用的数据结构,它们的主要区别在于数据的插入和删除顺序。

栈 (Stack) 是一种后进先出 (Last-In-First-Out, LIFO) 的数据结构,只允许在一端进行插入和删除操作,这一端称为栈顶。新元素插入后成为新的栈顶,而删除时也只能删除栈顶元素。

队列 (Queue) 是一种先进先出 (First-In-First-Out, FIFO) 的数据结构,允许在两端进行插入和删除操作,插入在队尾,删除在队头。新元素插入时成为新的队尾,而删除时也只能删除队头元素。

一.用队列模拟实现栈

1.void push(int x) 将元素 x 压入栈顶
2.int pop() 移除并返回栈顶元素
3.int top() 返回栈顶元素
4.boolean empty() 如果栈是空的,返回 true ;否则,返回 false

如上便是需要用队列来实现栈的四个基本操作。
我们试想,实现这些栈的操作,一个队列可以完成吗?
显然不可以,我们使用两个队列来实现栈的模拟
在这里插入图片描述

大体流程
1.入栈时:
如果两个都为空,那么想

1.1入栈

当我们要放入18 25 35 48 这一串数字入栈时,先放入18 25 35(放入时选择的队列是不为空的队列),模拟入队以及入栈时的状况,如下图
在这里插入图片描述

 public void push(int x) {if(empty()){queue1.offer(x);return;}if(!queue1.isEmpty()){queue1.offer(x);}else {queue2.offer(x);}}

1.2出栈

此时如果我们要将35出栈时,又该如何操作呢?此时我们就需要用到第二个队列,将队列一的前size-1个元素(也就是18 25)从队列一中出队,放入队列二中。此时队列一中的元素为35,队列二的元素为18 25 如下图。
在这里插入图片描述

当初栈完成时,我们此时要将48入栈时,又该放入哪个栈中呢?我们考虑栈的特点(先入后出),我们将再入栈的元素放到不为空的队列中。
在这里插入图片描述

 public int pop() {if(empty()){return -1;}if(!queue1.isEmpty()){int size = queue1.size();for (int i = 0; i < size-1; i++) {queue2.offer(queue1.poll());}return queue1.poll();}else {int size = queue2.size();for (int i = 0; i < size-1; i++) {queue1.offer(queue2.poll());}return queue2.poll();}}

1.3返回栈顶元素

在实现pop的基础上,我们将声明一个变量temp来储存每次要移除的元素。

  public int top() {if(empty()){return -1;}if (!queue1.isEmpty()){int temp = -1;int size = queue1.size();for (int i = 0; i < size; i++) {temp = queue1.poll();queue2.offer(temp);}return temp;}else {int size = queue2.size();int temp = -1;for (int i = 0; i < size; i++) {temp = queue2.poll();queue1.offer(temp);}return temp;}}

1.4判断栈是否为空

当队列一和队列二都为空时,此时栈就为空。

public boolean empty() {return queue1.isEmpty()&&queue2.isEmpty();}

二.用栈模拟实现队列

我们也是用两个栈来模拟实现队列

2.1 入队

我们将所有入队的元素都放入栈一中,如下图
在这里插入图片描述

public void push(int x) {stack1.push(x);}

2.2出队

要出栈时,如果栈二不为空,就出栈二中的元素,如果栈二为空,将栈一中的所有元素一次性的全部push到栈二中,此时就将入栈的元素全部倒转过来了,(例如入栈时在栈中的入栈顺序依次排序为18 25 35,栈二中此时的元素入栈顺序是35 25 18,出栈时就先出18,就完成了转换)如下图

在这里插入图片描述

 public int pop() {if(empty()){return -1;}if (stack2.isEmpty()){while (!stack1.isEmpty()){stack2.push(stack1.pop());}}return stack2.pop();}

2.3peek

peek只是将出队时的pop换成peek,就可以完成要求。

public int peek() {if(empty()){return -1;}if (stack2.isEmpty()){while (!stack1.isEmpty()){stack2.push(stack1.pop());}}return stack2.peek();}

2.4判断队列是否为空

如果栈一和栈二都为空时,那么队列就为空。

 public boolean empty() {return stack1.isEmpty() && stack2.isEmpty();}

三.完整代码

3.1 队列模拟实现栈

class MyStack {Queue<Integer> queue1 ;Queue<Integer> queue2 ;public MyStack() {queue1 = new LinkedList<>();queue2 = new LinkedList<>();}public void push(int x) {if(empty()){queue1.offer(x);return;}if(!queue1.isEmpty()){queue1.offer(x);}else {queue2.offer(x);}}public int pop() {if(empty()){return -1;}if(!queue1.isEmpty()){int size = queue1.size();for (int i = 0; i < size-1; i++) {queue2.offer(queue1.poll());}return queue1.poll();}else {int size = queue2.size();for (int i = 0; i < size-1; i++) {queue1.offer(queue2.poll());}return queue2.poll();}}public int top() {if(empty()){return -1;}if (!queue1.isEmpty()){int temp = -1;int size = queue1.size();for (int i = 0; i < size; i++) {temp = queue1.poll();queue2.offer(temp);}return temp;}else {int size = queue2.size();int temp = -1;for (int i = 0; i < size; i++) {temp = queue2.poll();queue1.offer(temp);}return temp;}}public boolean empty() {return queue1.isEmpty()&&queue2.isEmpty();}
}

3.2栈模拟实现队列

class MyQueue {public Stack<Integer> stack1 ;public Stack<Integer> stack2;public MyQueue() {stack1 = new Stack<>();stack2 = new Stack<>();}public void push(int x) {stack1.push(x);}public int pop() {if(empty()){return -1;}if (stack2.isEmpty()){while (!stack1.isEmpty()){stack2.push(stack1.pop());}}return stack2.pop();}public int peek() {if(empty()){return -1;}if (stack2.isEmpty()){while (!stack1.isEmpty()){stack2.push(stack1.pop());}}return stack2.peek();}public boolean empty() {return stack1.isEmpty() && stack2.isEmpty();}
}

相关文章:

  • Vue3使用 xx UI解决布局高度自适应
  • 机器视觉系统选型-高图像精度
  • 旅游景区项目信息化建设运营方案:PPT47页,附下载
  • ChatGPT如何计算token数?
  • 在Windows系统平台下部署运行服务端Idea工程的jar服务
  • 摄像头画面作为电脑桌面背景
  • 14:00面试,14:08就出来了,问的问题有点变态。。。
  • 【小白专用】php pdo sqlsrv 类,php连接sqlserver
  • 如何用 CleanMyMac 来保护 Mac 隐私
  • pyCharm 创建一个FastApi web项目,实现接口调用
  • English phrase
  • SQL server 数据库 sql常用语句
  • Achronix提供由FPGA赋能的智能网卡(SmartNIC)解决方案来打破智能网络性能极限
  • node.js mongoose aggregate
  • 用户管理第2节课-idea 2023.2 后端--删除表,从零开始
  • 【347天】每日项目总结系列085(2018.01.18)
  • 2017 前端面试准备 - 收藏集 - 掘金
  • 2017-09-12 前端日报
  • CSS魔法堂:Absolute Positioning就这个样
  • Druid 在有赞的实践
  • JavaScript设计模式与开发实践系列之策略模式
  • mysql常用命令汇总
  • Netty源码解析1-Buffer
  • Vue2.0 实现互斥
  • 大型网站性能监测、分析与优化常见问题QA
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 分布式任务队列Celery
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 小而合理的前端理论:rscss和rsjs
  • (poj1.2.1)1970(筛选法模拟)
  • (阿里云万网)-域名注册购买实名流程
  • ***通过什么方式***网吧
  • .jks文件(JAVA KeyStore)
  • .NET BackgroundWorker
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET Core中Emit的使用
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • [.NET]桃源网络硬盘 v7.4
  • [《百万宝贝》观后]To be or not to be?
  • [AS3]URLLoader+URLRequest+JPGEncoder实现BitmapData图片数据保存
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息
  • [bug总结]: Feign调用GET请求找不到请求体实体类
  • [C++基础]-初识模板
  • [C语言]——柔性数组
  • [LeetCode] 178. 分数排名
  • [Leetcode] 寻找数组的中心索引
  • [Lucas定理]【学习笔记】
  • [MongoDB]------windos下的安装部署与基础使用
  • [python] logging输出到控制台(标准输出)
  • [SpringBoot] AOP-AspectJ 切面技术
  • [Swift]LeetCode217. 存在重复元素 | Contains Duplicate
  • [three.js]UV动画
  • [win7-oracle处理方法]--java.lang.Exception: Exception in sending Request :: null(转)
  • [Windows编程] 取得Vista/Win7 下的 “下载” 目录路径