【Java数据结构】关于栈的操作出栈,压栈,中缀表达式,后缀表达式,逆波兰表达式详解

在这里插入图片描述

🔥个人主页:努力学编程’

🔥内容管理:java数据结构
请添加图片描述

上一篇文章我们讲过了java数据结构的链表,对于链表我们使用了它的一些基本操作,完成了扑克牌小游戏的操作,如果你感兴趣的话,点击超链接观看:【java数据结构】基于java提供的ArrayList实现的扑克牌游戏-(附源码~),今天带大家学习的是数据结构中另一个非常重要的知识-栈

目录

  • 1栈的一些基础知识
  • java代码实现一个栈
  • 对于栈功能的详解
    • 1.压栈:
    • 2.出栈pop:
    • 3.获取栈顶元素peek:
  • 逆波兰表达式求值:
    • 中缀表达式:
    • 后缀表达式:
  • 那么如何实现中缀表达式和后缀表达式的转换:
    • 解题思路:
    • 代码实现

1栈的一些基础知识

在开始前,请牢记这句话:栈是一种先进后出的数据结构。栈(stack)是限定仅在表的一端进行操作的数据结构,请联系我们前文所学的,设想一个单链表我们只能够对其链表的表尾结点进行操作,而操作也只能够进行插入一个新的结点与删除最末尾的这个结点两个操作,而这样强限制性的‘链表’,就是我们所说的栈。

栈在底层逻辑的实现上可分为链表栈和数组栈:

栈分为数组栈和链表栈,其区别是数组栈使用数组进行功能的模拟,实现较为快速和便利,而链表栈使用链表的思路去设计,实现较为麻烦,但是其稳定不易出错;在链表栈中又分为静态链表栈和动态链表栈,静态链表栈给定栈的空间大小,不允许超过存储超过给定数据大小的元素,而动态栈使用的是自动创建空间的方法进行创建,只要符合机器的硬件要求以及编译器的控制,其理论上是极大的。

以下是实现一个栈的具体操作过程:

1.选择数据结构:
栈可以使用数组(或列表)或链表来实现。数组实现的栈通常更简单,因为它们具有随机访问的能力,而链表实现的栈可能需要更多的指针操作。

2.定义栈的操作:
定义栈的基本操作,包括入栈(push)、出栈(pop)、获取栈顶元素(peek)等

3.确定栈的大小(如果有限制): 如果栈有大小限制,则需要确定栈的最大容量。如果栈的大小是动态的,则可以跳过此步骤。

4.实现栈的基本操作:
根据选择的数据结构,实现栈的基本操作。如果使用数组实现,通常使用数组的末尾作为栈的顶部,入栈操作将元素添加到数组末尾,出栈操作将从数组末尾移除元素。如果使用链表实现,需要定义节点类,并根据栈的操作更改节点的连接关系。

5.处理边界情况:
在实现栈的操作时,要考虑边界情况,如栈为空时尝试出栈或查看栈顶元素,或者栈已满时尝试入栈。

6.测试栈的实现:
编写测试代码,确保栈的实现能够正常工作,并处理各种情况,如入栈、出栈、查看栈顶元素、栈为空或栈已满等。

7.优化(如果需要)
根据实际需求和性能要求,可以对栈的实现进行优化,例如使用动态数组实现以处理栈大小动态变化的情况,或者使用链表实现以节省内存空间。

通过以上步骤,你可以实现一个简单而有效的栈数据结构。

java代码实现一个栈

import java.util.ArrayList;
import java.util.EmptyStackException;public class Stack {private ArrayList<Integer> stack;private int maxSize;// 构造函数public Stack(int maxSize) {this.maxSize = maxSize;this.stack = new ArrayList<>();}// 判断栈是否为空public boolean isEmpty() {return stack.isEmpty();}// 判断栈是否已满public boolean isFull() {return stack.size() == maxSize;}// 入栈操作public void push(int item) {if (isFull()) {System.out.println("Stack is full. Cannot push element.");} else {stack.add(item);}}// 出栈操作public int pop() {if (isEmpty()) {throw new EmptyStackException();}return stack.remove(stack.size() - 1);}// 获取栈顶元素但不移除public int peek() {if (isEmpty()) {throw new EmptyStackException();}return stack.get(stack.size() - 1);}// 获取栈的大小public int size() {return stack.size();}// 主函数用于测试public static void main(String[] args) {Stack stack = new Stack(5);// 入栈操作stack.push(1);stack.push(2);stack.push(3);stack.push(4);stack.push(5);// 获取栈的大小System.out.println("Stack size: " + stack.size());// 出栈操作System.out.println("Pop element: " + stack.pop());System.out.println("Pop element: " + stack.pop());// 获取栈顶元素System.out.println("Peek element: " + stack.peek());// 获取栈的大小System.out.println("Stack size: " + stack.size());}
}

对于栈功能的详解

1.压栈:

向栈里插入数据,称为压栈,下面为图解:

在这里插入图片描述

既然栈我们底层用的是数组实现,那么在我们压栈的时候,就必须考虑一件事情,数组是否已满,如果数组已经放满了,我们就必须先对数组进行扩容,然后才能对数据进行插入

那么具体应该如何对栈实现扩容呢,其实和数组扩容是一个道理:

 public void push(int val){if(isFull()){Arrays.copyOf(elem,2*elem.length);}elem[usedSize]=val;usedSize++;}public boolean isFull(){return usedSize== elem.length;}

2.出栈pop:

将栈顶的元素弹出,后面的元素接替成为栈顶元素,属于栈的基本操作

在这里插入图片描述
下面是使用java实现的pop方法:

public int pop(){if(empty()){return -1;}int oldVal=elem[usedSize-1];usedSize--;return oldVal;}public boolean empty(){return usedSize==0;}

将栈顶的元素返回,具体对于栈数据的删除,其实就是将usedSize–,代表将数组的大小进行了调整。

3.获取栈顶元素peek:

本质上其实就是将栈顶元素进行打印,需要注意的一点这个方法返回栈顶的元素但不移除它。

 public int pop(){if(empty()){return -1;}int oldVal=elem[usedSize-1];usedSize--;return oldVal;}public boolean empty(){return usedSize==0;}public int peek(){if(empty()){return -1;}return elem[usedSize-1];}
}

以上就是对于栈的一些基本操作,了解完这些知识,我们就可以使用栈的知识解决一些算法题

逆波兰表达式求值:

点击链接一起挑战,逆波兰表达式求值要想解决这道题,我们需要首先了解中缀表达式,后缀表达式的知识

中缀表达式:

中缀表达式是我们最常见的数学表达式形式,它采用操作符位于操作数之间的形式。例如,“3 + 4”、“(5 - 2) * 6” 等都是中缀表达式。

中缀表达式的特点包括:

1.操作符在操作数中间:例如,“3 + 4” 中的加号就位于操作数 3 和 4 之间。
2.使用括号:中缀表达式通常需要使用括号来明确运算的优先级和顺序。
3.常见的运算符优先级规则:乘除法优先于加减法,同级运算符按照从左到右的顺序计算。

后缀表达式:

后缀表达式,也称为逆波兰表达式(Reverse Polish Notation,RPN),是一种不需要括号来表示运算顺序的数学表达式形式。在后缀表达式中,操作符在操作数之后出现,因此不需要括号来明确运算的顺序。

后缀表达式的主要特点是:

1.没有括号:
不需要括号来指定运算次序,因为操作符始终跟在操作数之后。
2.明确运算顺序:
从左到右扫描表达式,每当遇到一个操作符,就从栈中弹出足够的操作数进行计算,然后将结果压回栈中,直到整个表达式扫描完毕。
3.简化计算:
后缀表达式减少了运算符的优先级问题,简化了计算过程。
例如,将中缀表达式 "3 + 4 * 5" 转换为后缀表达式为 "3 4 5 * +"

处理后缀表达式的算法通常使用栈来实现。具体步骤如下:

1.从左到右遍历后缀表达式的每个字符。
2.如果遇到操作数,则将其压入栈中。
3.如果遇到操作符,则从栈中弹出相应数量的操作数进行运算,并将结果压入栈中。
4.最终栈中只剩下一个元素,即为后缀表达式的计算结果。

那么如何实现中缀表达式和后缀表达式的转换:

这里给大家分享一个方法
1.首先将表达式严格改为中缀表达式
2.把每个运算符转移到对应括号的后面
3.完成后缀表达式的转化
在这里插入图片描述

解题思路:

在这里插入图片描述

代码实现

 public int evalRPN(String[] tokens) {int n = tokens.length;int[] stack = new int[(n + 1) / 2];int index = -1;for (int i = 0; i < n; i++) {String token = tokens[i];switch (token) {case "+":index--;stack[index] += stack[index + 1];break;case "-":index--;stack[index] -= stack[index + 1];break;case "*":index--;stack[index] *= stack[index + 1];break;case "/":index--;stack[index] /= stack[index + 1];break;default:index++;stack[index] = Integer.parseInt(token);}}return stack[index];}

好了,今天就分享到这里,谢谢大家!

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

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

相关文章

MATLAB 自定义均值滤波 (53)

MATLAB 自定义均值滤波 (53) 一、算法介绍二、算法实现1.原理2.代码一、算法介绍 均值滤波,是一种常见的点云平滑算法,改善原始点云的数据质量问题,MATLAB自带的工具似乎不太友好,这里提供自定义实现的点云均值滤波算法,具体效果如下所示: 均值滤波前: 均值滤波后:…

Pycharm选择使用Anaconda环境中的Pytorch 失败解决办法之一

前几日想要复现一篇论文&#xff0c;结果给配的台式机完全禁不住&#xff0c;老是报溢出&#xff0c;慢都没事&#xff0c;溢出就很难受了&#xff0c;因此想用自己笔记本的GPU来训练。 安装以后遇到一个问题&#xff1a; Anaconda里创建了环境&#xff0c;安装好了对应pytor…

RPC--远程调用

通信调用 程序A(加密) 程序B 内存共享 (本地RPC) 发送窗口信息 (本地RPC) --长度有限制 串口通讯 com口 --浏览器不开串口... 通讯管道(防止多开) (本地RPC) --对我们不可见. 网络 TCP/IP (远程RPC) --good! 浏览器(, ws) <--- 任意语言开发的软件 --任意语言控制浏览器. 注…

Linux基础知识

文章目录 一、入门命令&#xff1a;1.find 条件 要查找的文件满足的条件&#xff08;从当前目录开始查找&#xff09;&#xff1a;2.locate 文件名&#xff1a;3.lear CTRL L &#xff08;清除终端窗口&#xff09;与cat&#xff08;打印输出文件内容&#xff09;&#xff1a…

网络性能提升10%,ZStack Edge 云原生超融合基于第四代英特尔®至强®可扩展处理器解决方案发布

随着业务模式的逐渐转变、业务架构逐渐变得复杂&#xff0c;同时容器技术的兴起和逐渐成熟&#xff0c;使得Kubernetes、微服务等新潮技术逐步应用于业务应用系统上。 为了充分释放性能、为业务系统提供更高效的运行环境&#xff0c;ZStack Edge 云原生超融合采用了第四代英特尔…

ROS传感器图像转换

ros通过摄像头来获得图片&#xff0c;传感器数据类型为sensor_msgs中的Image&#xff0c;具体的数据类型组成&#xff1a; sensor_msgs/Image Documentationhttp://docs.ros.org/en/api/sensor_msgs/html/msg/Image.html但是我们一般使用opencv对图像进行处理&#xff0c;所以…

elementui 导航菜单栏和Breadcrumb 面包屑关联

系列文章目录 一、elementui 导航菜单栏和Breadcrumb 面包屑关联 文章目录 系列文章目录前言一、elementui 导航菜单栏和Breadcrumb 面包屑怎么关联&#xff1f;二、实现效果三、实现步骤1.本项目演示布局2.添加面包屑2.实现breadcrumbName方法3.监听方法4.路由指配5.路由配置…

全国青少年软件编程(Python)等级考试三级考试真题2023年12月——持续更新.....

青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;三级&#xff09; 分数&#xff1a;100 题数&#xff1a;38 一、单选题(共25题&#xff0c;共50分) 1.一个非零的二进制正整数&#xff0c;在其末尾添加两个“0”&#xff0c;则该新数将是原数的&#xf…

具备实时数据更新能力的大语言模型——Larimar

ChatGPT、Claude.ai等大模型产品就像“图书馆”一样为我们生成各种各样的内容。但是想更新这个图书馆里的知识却不太方便&#xff0c;经常需要漫长、费时的预训练、蒸馏才能完成。 研究人员提出了一种具有情景记忆控制的大语言模型Larimar&#xff0c;这是一种类似人脑"海…

love 2d win 下超简单安装方式,学习Lua 中文编程 刚需!!

一、下载love 2d 参考&#xff1a;【Love2d从青铜到王者】第一篇:Love2d入门以及安装教程 或直接下载&#xff1a; 64位&#xff0c;现在一般电脑都可以用。 64-bit zipped 32位&#xff0c;很复古的电脑都可以用。 32-bit zipped 二、解压 下载好了之后&#xff0c;解压到…

css3之动画animation

动画animation 一.优点二.定义和使用三.动画序列和解释四.常见属性及解释五.简写&#xff08;名字和时间不能省略&#xff09;&#xff08;持续时间在何时开始的时间前&#xff09;&#xff08;简写中无animation-play-state)六.例子1.大数据热点图2.奔跑的熊大&#xff08;一个…

vitess执行计划缓存 测试

打开执行计划器缓存&#xff1a; sysbench /usr/local/share/sysbench/oltp_write_only.lua --mysql-host127.0.0.1 --mysql-port15306 --mysql-userroot --mysql-password --mysql-dbcustomer --report-interval10 100s sysbench /usr/local/share/sysbench/oltp_read_only.l…

vlanif三层交换机实现不同网络通信

实验目的&#xff1a;通过三层交换机实现不同 网络通信&#xff0c;之前都是路由器进行不同网络转发 拓扑图 内容&#xff1a;左边vlan10&#xff0c;右边vlan20 lsw1接口通过所有vlan lsw2网路vlan10 lsw3网络vlan20 问题点&#xff1a;开始只是配置了最上面LSW1的交换机…

三台电机的顺启逆停

1&#xff0c;开启按钮输入信号是 电机一开始启动&#xff0c;5秒回电机2启动 &#xff0c;在5秒电机三启动 关闭按钮输入时电机3关闭 &#xff0c;5秒后电机2关闭 最后电机一关闭 2&#xff0c;思路开启按钮按下接通电机1 并且接通定时器T0 定时器T0 到时候接通电机2 并且开…

Predict the Next “X” ,第四范式发布先知AIOS 5.0

今天&#xff0c;第四范式发布了先知AIOS 5.0&#xff0c;一款全新的行业大模型平台。 大语言模型的原理是根据历史单词去不断预测下一个单词&#xff0c;换一句常见的话&#xff1a;Predict the Next “Word”。 当前对于行业大模型的普遍认知就是沿用这种逻辑&#xff0c;用大…

聊聊多版本并发控制(MVCC)

多版本并发控制&#xff08;MVCC&#xff09; MVCC一直是数据库部分的高频面试题&#xff0c;这篇文章来聊聊MVCC是什么&#xff0c;以及一些底层原理的实现。 当前读和快照读&#xff1a; 当前读&#xff1a;读取的是事务最新的版本&#xff0c;读取的过程中其他并发事务不…

适用于 Windows 的 6 个最佳视频转换器

视频转换器可以帮助您在设备上转换和播放不受支持的视频格式。它还可以方便地减小视频文件大小、以通用格式组织所有视频或与其他人共享文件以在不同设备上播放。 Windows 有大量视频转换器可供选择。虽然有些是免费的&#xff0c;但其他一些则提供迎合专业用户的高级功能。在…

【DETR系列目标检测算法代码精讲】01 DETR算法01 DETR算法框架和网络结构介绍

为什么要有DETR 总所周知&#xff0c;传统的目标检测算法非常依赖于anchor和nms等手工设计操作&#xff0c;非常费时费力&#xff0c;自然而然的就产生了取消这些操作的想法。但是我们首先需要思考的是&#xff0c;为什么我们需要anchor和nms&#xff1f; 因为我们是没有指定…

安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 从0开始 工具操作解析【三】

同类博文; 安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 工具操作解析 安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 工具操作解析【二】-CSDN博客 回顾以往 在以前的博文简单介绍了这款工具的rom制作全程。今天针对这款工具的…

【Java多线程】8——CompletableFuture

8 CompletableFuture ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个s…