Java-----栈

目录

1.栈(Stack)

1.1概念

1.2栈的使用

1.3栈的模拟实现

1.4栈的应用场景

1.5栈、虚拟机栈、栈帧有什么区别呢


1.栈(Stack)

1.1概念

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据在栈顶。

1.2栈的使用

方法功能
Stack()构造一个空的栈
E push(E e)将e入栈,并返回e
E pop()将栈顶元素出栈并返回
E peek()获取栈顶元素
int size()获取栈中有效元素个数
boolean empty()检测栈是否为空
    public static void main(String[] args) {
Stack<Integer>stack=new Stack<>();
//进栈
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);System.out.println(stack);//出栈stack.pop();stack.pop();System.out.println(stack);//判断栈是否为空System.out.println(stack.empty());//获取栈顶元素System.out.println(stack.peek());//获取元素个数System.out.println(stack.size());}

1.3栈的模拟实现

使用数组实现

package MyStack;import java.util.Arrays;public class MyStack {public int[]elem;public int useSize=0;
//构造方法public MyStack() {this.elem =new int[10];}
//出栈public int pop(){if(empty()){throw new StackemptyExpection("栈为空,无法出栈");}return elem[useSize--];}
//进栈public void push(int val){if(isFull()){this.elem= Arrays.copyOf(elem,elem.length*2);}
elem[useSize]=val;
useSize++;}
//获取栈顶元素public int peek(){
return elem[useSize-1];}
//判断是否为空public boolean empty(){
return useSize==0;}
//判断是否满了public boolean isFull(){return useSize== elem.length;}}

1.4栈的应用场景

1. 改变元素的序列

1. 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()  

A: 1,4,3,2   B: 2,3,4,1   C: 3,1,4,2   D: 3,4,2,1    

答案:C

2.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的顺序是( )。

A: 12345ABCDE   B: EDCBA54321   C: ABCDE12345   D: 54321EDCBA

答案:B

2. 将递归转化为循环

逆序打印链表

// 递归方式
void printList(Node head){if(null != head){printList(head.next);System.out.print(head.val + " ");}
}// 循环方式
void printList(Node head){if(null == head){return;}Stack<Node> s = new Stack<>();// 将链表中的结点保存在栈中Node cur = head;while(null != cur){s.push(cur);cur = cur.next;}// 将栈中的元素出栈while(!s.empty()){System.out.print(s.pop().val + " ");}
}

3.有效的括号

. - 力扣(LeetCode)

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

 方法:

创建一个栈用来存储左括号,遍历字符串,如果是左括号就将其进栈,否则判断其是否和栈顶括号匹配,如果栈顶没有元素返回false,如果匹配就出栈,遍历完看栈是否为空,不为空返回false,为空返回true

class Solution {public boolean isValid(String s) {
Stack<Character>stack=new Stack<>();
for(int i=0;i<s.length();i++){char ch=s.charAt(i);if(ch=='('||ch=='{'||ch=='['){stack.push(ch);}else{if(stack.isEmpty()){return false;}
char ch2=stack.peek();
if((ch==')'&&ch2=='(')||(ch=='}'&&ch2=='{')||(ch==']'&&ch2=='['))
{stack.pop();
}else{return false;
}}
}
if(!stack.isEmpty()){return false;
}
return true;}
}

4.逆波兰表达式求值

. - 力扣(LeetCode)

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

方法:

创建一个栈来存储数字,遍历字符串数组,如果是数字就进栈,不是就连续出栈两个数字进行计算,计算的结果再进栈,遍历完数组后,返回栈顶元素

class Solution {public int evalRPN(String[] tokens) {
Stack<Integer>stack=new Stack<>();
for(String str:tokens){if(!isOperator(str)){int x=Integer.parseInt(str);
stack.push(x);}else{
int val2=stack.pop();
int val1=stack.pop();
switch(str){
case "+":
stack.push(val1+val2);
break;
case "-":
stack.push(val1-val2);
break;
case "*":
stack.push(val1*val2);
break;
case "/":
stack.push(val1/val2);
break;
}}
}
return stack.pop();}
private boolean isOperator(String str){if(str.equals("+")||str.equals("-")||str.equals("/")||str.equals("*")){return true;}return false;
}
}

中缀表达式怎么变后缀表达式

将中缀表达式转换为后缀表达式可以通过以下步骤进行:

1. 初始化一个空栈用于存储运算符,以及一个空字符串用于存储后缀表达式。

2. 从左到右依次扫描中缀表达式的每个元素。

• 如果是操作数,直接添加到后缀表达式中。

• 如果是左括号,将其入栈。

• 如果是右括号,将栈中的运算符依次弹出并添加到后缀表达式中,直到遇到左括号,然后将左括号从栈中弹出。

• 如果是运算符:

• 若栈为空或栈顶为左括号,直接将运算符入栈。

• 若该运算符的优先级高于栈顶运算符的优先级,将其入栈。

• 若该运算符的优先级低于或等于栈顶运算符的优先级,将栈顶运算符弹出并添加到后缀表达式中,然后比较新的栈顶运算符,重复此操作,直到该运算符可以入栈。

3. 扫描完毕后,将栈中剩余的运算符依次弹出并添加到后缀表达式中。

例如,将中缀表达式“3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3”转换为后缀表达式:

扫描到“3”,是操作数,直接添加到后缀表达式,后缀表达式为“3”。

扫描到“+”,栈为空,入栈,栈内为“+”,后缀表达式为“3”。

扫描到“4”,是操作数,添加到后缀表达式,后缀表达式为“3 4”。

扫描到“”,“+”优先级低于“”,“*”入栈,栈内为“+ *”,后缀表达式为“3 4”。

扫描到“2”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2”。

扫描到“/”,“”优先级高于“/”,将“”弹出,“/”入栈,栈内为“+ /”,后缀表达式为“3 4 2 *”。

扫描到“(”,入栈,栈内为“+ / (”,后缀表达式为“3 4 2 *”。

扫描到“1”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2 * 1”。

扫描到“-”,栈顶为“(”,入栈,栈内为“+ / ( -”,后缀表达式为“3 4 2 * 1”。

扫描到“5”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2 * 1 5”。

扫描到“)”,将栈中运算符依次弹出直到遇到“(”,“(”弹出,栈内为“+ / ”,后缀表达式为“3 4 2 * 1 5 -”。

扫描到“^”,“/”优先级低于“^”,“^”入栈,栈内为“+ / ^”,后缀表达式为“3 4 2 * 1 5 -”。

扫描到“2”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2 * 1 5 - 2”。

扫描到“^”,“^”优先级高于栈顶“^”,入栈,栈内为“+ / ^ ^”,后缀表达式为“3 4 2 * 1 5 - 2”。

扫描到“3”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2 * 1 5 - 2 3”。

扫描结束,将栈中运算符依次弹出添加到后缀表达式,最终后缀表达式为“3 4 2 * 1 5 - 2 ^ 3 ^ / + ”

5.栈的压入和弹出序列

栈的压入、弹出序列_牛客题霸_牛客网

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
1. 0<=pushV.length == popV.length <=1000
2. -1000<=pushV[i]<=1000
3. pushV 的所有数字均不相同

 方法:

遍历一遍pushV数组,先将pushV中的元素压栈,判断栈顶元素是否和popV的j下标元素相同,相同就出栈,继续判断,直到不相同为止,当遍历完pushV时,看栈是否为空,如果为空,则说明popV是可行的出栈序列,否则不是

    public boolean IsPopOrder (int[] pushV, int[] popV) {Stack<Integer>stack=new Stack<>();int j=0;for(int i=0;i<pushV.length;i++){
stack.push(pushV[i]);
while(!stack.empty()&&stack.peek()==popV[j]&&j<popV.length){stack.pop();j++;
}}return stack.empty();}
}

6.最小栈

. - 力扣(LeetCode)

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。

 方法

构造方法创建一个普通栈和最小栈

push方法,普通栈是必须压栈的,当普通栈压栈完成后,比较普通栈和最小栈的栈顶元素,如果普通栈的栈顶元素小于或等于最小栈的栈顶元素,那么就对最小栈进行压栈

pop方法,接收普通栈的栈顶元素,普通栈出栈,如果栈顶元素和最小栈的栈顶元素相同,那么最小栈也出栈

top方法,如果普通栈为空,返回-1,否则返回普通栈的栈顶元素

getMin方法,如果最小栈为空,返回-1,否则返回最小栈的栈顶元素

class MinStack {
public Stack<Integer>stack;
public Stack<Integer>Minstack;public MinStack() {
this.stack=new Stack<>();
this.Minstack=new Stack<>();}public void push(int val) {
stack.push(val);
if(Minstack.empty()){Minstack.push(val);
}else{if(val<=Minstack.peek()){Minstack.push(val);}
}}public void pop() {
int popVal=stack.pop();
if(popVal==Minstack.peek()){Minstack.pop();
}}public int top() {
if(stack.empty()){return -1;
}
return stack.peek();}public int getMin() {
if(Minstack.empty()){return -1;
}
return Minstack.peek();}
}

1.5栈、虚拟机栈、栈帧有什么区别呢?

栈(Stack)是一种数据结构,具有“后进先出”的特点,常用于存储临时数据和函数调用信息。
虚拟机栈(Virtual Machine Stack)是 Java 虚拟机运行时数据区中的一部分,用于存储方法调用的相关信息,包括局部变量表、操作数栈、动态链接、方法出口等。
栈帧(Stack Frame)是虚拟机栈中的基本单位,每当一个方法被调用时,就会创建一个新的栈帧并压入虚拟机栈。栈帧包含了方法的局部变量、操作数栈、返回地址等信息。当方法执行完毕,对应的栈帧就会出栈。

总的来说,栈是一种通用的数据结构概念,虚拟机栈是 Java 虚拟机中基于栈这种数据结构实现的用于方法调用管理的区域,而栈帧是虚拟机栈中的具体存储单元,用于承载每个方法的相关运行信息。

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

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

相关文章

EEtrade:区块链是什么

区块链&#xff0c;这个近年来频繁出现在我们视野中的术语&#xff0c;已经从一个技术小众圈的词汇&#xff0c;逐渐演变为全球关注的焦点。从比特币的诞生&#xff0c;到如今在金融、供应链、物联网等领域的广泛应用&#xff0c;区块链技术正在深刻地改变着我们的生活。那么&a…

我在高职教STM32——串口通信(5)

大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正因如此,才有了借助 CSDN 平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思的教学设计分享…

【linux】Shell脚本三剑客之grep和egrep命令的详细用法攻略

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

LK漏感值在网络变压器测试中是否有很大的作用?

今天客户一个产品异常问题&#xff0c;就是说LK漏感值严重超标产品规格书参数&#xff0c;今天我们讲讲这个参数在网络变压器其中的影响。LK漏感值在网络变压器的测试和性能评估中扮演着重要的角色。漏感&#xff0c;或称为漏磁场感抗&#xff0c;是指变压器中不参与主要能量传…

springboot会员信息管理系统-计算机毕业设计源码38258

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3开发技术 1.3.1 Spring Boot框架 1.3.2 Java语言 1.3.3 MySQL数据库 1.4论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 登录流程 2.2.2数据删除流程 2.3 系统功能分析 2.4 系统用例分析…

《Java初阶数据结构》----8.<java对象的比较总结>

目录 前言 一、Java对象的比较 1.1基本类型的比较 1.2 对象比较的问题&#xff08;与equals&#xff09; 1.3对象的比较 &#xff08;三种常用方式&#xff09; 1.重写equals方法 2.基于Comparble接口类的比较 3.基于比较器比较&#xff08;Comparator接口&#xff09; …

秒懂C++之string类(下)

目录 一.接口说明 1.1 erase 1.2 replace&#xff08;最好别用&#xff09; 1.3 find 1.4 substr 1.5 rfind 1.6 find_first_of 1.7 find_last_of 二.string类的模拟实现 2.1 构造 2.2 无参构造 2.3 析构 2.4.【】运算符 2.5 迭代器 2.6 打印 2.7 reserve扩容 …

大模型算法面试题(十二)

本系列收纳各种大模型面试题及答案。 1、领域模型Continue PreTrain数据如何选取 在领域模型的Continue PreTrain&#xff08;持续预训练&#xff09;过程中&#xff0c;数据选取是一个至关重要的步骤&#xff0c;它直接影响模型在特定领域上的性能和泛化能力。以下是一些关于…

Transformer-Bert---散装知识点---mlm,nsp,较之经典tran的区别和实际应用方式

本文记录的是笔者在了解了transformer结构后嗑bert中记录的一些散装知识点&#xff0c;有时间就会整理收录&#xff0c;希望最后能把transformer一个系列都完整的更新进去。 1.自监督学习 bert与原始的transformer不同&#xff0c;bert是使用大量无标签的数据进行预训练&#…

batch norm记录

文章目录 概要整体架构流程训练阶段推理阶段模型中使用的注意事项 概要 面试百度时候被问到了BN 内部详细的训练阶段&#xff0c;推理阶段的计算过程。没回答好&#xff0c;来记录一下 推荐一下b站up: Enzo_Mi。视频做的确实不错 bn 讲解视频 整体架构流程 训练阶段 均值和标…

【C/C++】printf和cout的区别

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

C++初阶学习——探索STL奥秘——标准库中的string类

1. 为什么学习string类&#xff1f; 在我们学习C语言的时候&#xff0c;有一个点是非常难处理的&#xff0c;那就是字符串&#xff0c;在我们对字符串访问&#xff0c;增删查改时都是非常不便的&#xff0c;所以我们封装了一个string类主要来处理字符串有关的问题 2. 标准库中…

多模态论文一:CLIP模型主要内容讲解【原理+代码】

一、CLIP模型主要内容讲解 CLIP&#xff08;Contrastive Language-Image Pre-training&#xff09;是OpenAI在2021年发布的一种用于图像和文本联合表示学习的模型。CLIP的核心思想是通过对比学习来预训练一个模型&#xff0c;使其能够理解图像和文本之间的关系。以下是CLIP的工…

数据传输安全--SSL VPN

目录 IPSEC在Client to LAN场景下比较吃力的表现 SSL VPV SSL VPN优势 SSL协议 SSL所在层次 SSL工作原理 SSL握手协议、SSL密码变化协议、SSL警告协议三个协议作用 工作过程 1、进行TCP三次握手、建立网络连接会话 2、客户端先发送Client HELLO包&#xff0c;下图是包…

Oracle对比两表数据的不一致

MINUS 基本语法如下 [SQL 语句 1] MINUS [SQL 语句 2];举个例子&#xff1a; select 1 from dual minus select 2 from dual--运行结果 1-------------------------------- select 2 from dual minus select 1 from dual--运行结果 2所以&#xff0c;如果想找所有不一致的&a…

【数据结构】二叉树链式结构——感受递归的暴力美学

前言&#xff1a; 在上篇文章【数据结构】二叉树——顺序结构——堆及其实现中&#xff0c;实现了二叉树的顺序结构&#xff0c;使用堆来实现了二叉树这样一个数据结构&#xff1b;现在就来实现而二叉树的链式结构。 一、链式结构 链式结构&#xff0c;使用链表来表示一颗二叉树…

FPGA:有限状态机

从以下6个实验理解状态机的概念 开发板频率为 50 M H z 50MHz 50MHz&#xff0c;一个时钟周期是 20 n s 20ns 20ns。 1、实验一:LED灯亮0.25秒、灭0.75秒的状态循环 通过之前的分析&#xff0c;我们实现频闪灯时&#xff0c;是让led灯在0.5秒实现一次翻转&#xff0c;而这里…

经典文献阅读之--World Models for Autonomous Driving(自动驾驶的世界模型:综述)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…

html+css 实现水波纹按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…

vue3前端开发-小兔鲜项目-使用pinia插件完成token的本地存储

vue3前端开发-小兔鲜项目-使用pinia插件完成token的本地存储&#xff01;实际业务开发中&#xff0c;token是一个表示着用户登录状态的重要信息&#xff0c;它有自己的生命周期。因此&#xff0c;这个参数值必须实例化存储在本地中。不能跟着pinia。因为pinia是基于内存设计的模…