Java - 数据结构,栈
一、栈
1.1、什么是栈
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈
顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据在栈顶
什么是Java虚拟机栈?
java虚拟机栈也是栈,就是JVM中的一块内存,也是符合栈的规则 – 先进后出规则方法区:存放类定义信息、字节码、常量等数据,在Sun HotSpot JVM中,这块也称为Perm Gen。
堆:创建的对象信息将放入堆中,堆内部如何实现各虚拟机各不相同,对于Sun HotSpot JVM来说又分为Young Gen和Tenured Gen,更详细描述参见《[Java性能剖析]Sun JVM内存管理和垃圾回收 》
Java栈:对于每个执行线程,会分配一个Java栈,JVM在执行过程当中,每执行一个方法,都会为方法在当前栈中增加一个栈帧,每个栈帧的信息与具体实现相关,但一般会由3部分组成:变量区,方法参数和本地变量会放入这个位置,大小是固定的,在进行方法时会先分配好,在类定义中,会由max local来指定这块区的大小;方法信息区,会包括当前类常量池的入口地址等信息,这块大小也是固定的;操作栈,与Intel体系架构中的运算使用寄存器来进行不一样,JVM的字节码的方法调用、运算等需要的参数,都是通过操作栈来传递的。在类定义中,会由max stack指定最大的操作栈。关于Java栈的更详细描述参见《Java 栈内存介绍 》
本地方法栈:对本地方法的调用,并不会使用Java栈而是使用本地方法栈,本地方法栈的组成取决于所使用的平台和操作系统.
PC寄存器/程序计数器:对于每个执行线程会分配一个PC寄存器,寄存器中存放当前字节码的执行位置什么是栈帧?
调用函数的时候,我们会为函数开辟一块内存,这块内存叫做栈帧,这个内存在Java虚拟机栈中开辟
2.2、栈的笔试题
2.2.1、一个栈的输入顺序是ABCDEF,那么不可能出现的出栈顺序是什么()
A、DCBAEF
B、ACBEDF
C、DEFBCA
D、CDBAFE
在出栈的时候可以入一个出一个,入栈和出栈的顺序可以打乱,但是出栈的时候,一定是先出栈顶的元素
剑指 Offer 31. 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。
public boolean validateStackSequences(int[] pushed, int[] popped) {Stack<Integer> stackA = new Stack<Integer>();int j = 0;//遍历数组pushedfor(int i = 0; i < pushed.length; i++){stackA.push(pushed[i]);//判断栈顶元素是否和popped数组的j下标相等,如果相等就出栈while(j < popped.length && !stackA.empty() && stackA.peek() == popped[j]){stackA.pop();j++;} }return stackA.empty();}
2.2.2、中缀表达式转后缀表达式
它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。
举例:
(3 + 4) × 5 - 6 就是中缀表达式
-× + 3 4 5 6 前缀表达式
3 4 + 5 × 6 - 后缀表达式
中缀表达式(中缀记法)
中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。
虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单。
前缀表达式(前缀记法、波兰式)
前缀表达式的运算符位于操作数之前。
后缀表达式(后缀记法、逆波兰式)
后缀表达式与前缀表达式类似,只是运算符位于操作数之后。
如何将中缀表达式转换成后缀表达式
利用栈实现计算后缀表达式的值:逆波兰表达式求值
class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack = new Stack<>();for(int i = 0; i < tokens.length; i++){String val = tokens[i];if(isOperator(val) == false){stack.push(Integer.parseInt(val));}else {int num2 = stack.pop();int num1 = stack.pop();switch (val){case "+":stack.push(num1 + num2);break;case "-":stack.push(num1 - num2);break;case "*":stack.push(num1 * num2);break;case "/":stack.push(num1 / num2);break; }}}return stack.pop();}//判断是不是运算符,是就返回true,不是就返回FALSEprivate boolean isOperator(String val){if(val.equals("+") || val.equals("-") || val.equals("*") || val.equals("/")){return true;}return false;}
}
2.3、栈的方法
public static void main(String[] args) {Stack<Integer> stack = new Stack<>();stack.push(1);stack.push(2);stack.push(3);stack.push(4);System.out.println(stack);System.out.println(stack.pop());System.out.println(stack);stack.peek();System.out.println(stack);}
2.4、模拟实现一个栈
public class MyStack {public int elem[];public int usedSize;public MyStack(){//源码中默认大小为10this.elem = new int[10];}//添加元素public void push(int val){//判断是否满if(isFull()){//如果满了就要扩容,this.elem = Arrays.copyOf(elem, 2*this.usedSize);}this.elem[this.usedSize] = val;this.usedSize++;}private boolean isFull(){//满了返回truereturn this.elem.length == this.usedSize;}//出栈public int pop(){//首先要判断栈里面有没有元素if(empty()){//如果没有元素就不能出栈,此时就要抛出异常throw new RuntimeException("栈为空!");}//如果有元素就可以出栈了int oldVal = this.elem[usedSize-1];//如果栈里面存的是引用类型,那这个就要置位nullusedSize--;return oldVal;}public boolean empty(){return this.usedSize == 0;}//获取栈顶元素public int peek(){//首先要判断栈里面有没有元素if(empty()){//如果没有元素就不能出栈,此时就要抛出异常throw new RuntimeException("栈为空!");}return this.elem[usedSize-1];}}
面试题:能不能用单链表实现一个栈
首先,要实现一个栈,就要知道栈的特点
1、先进后出
2、入栈和出栈的时间复杂度是O(1)
那单链表呢,单链表可以头插和尾插,那用头插还是插???
如果用头插:在入栈的时候就头插,时间复杂度也是O(1),出栈的时候只要删除头结点,时间复杂度也是O(1)。
如果用尾插:那就不可能实现,在插入的时候可以用尾插,时间复杂度是O(1),但是在出栈的时候就不行了,在删除尾巴节点的时候,要知道尾巴节点的前驱才能删除,但是这时候就要遍历一遍链表,时间复杂度就是O(n)
那单链表不行,就可以使用双向链表。
有效的括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
/在做这道题的时候要考虑几种情况//1、左括号多了 ((( ))//2、右括号多了 ((((( ))//2、括号不匹配 ( [ ] } public boolean isValid(String s) {//栈里面存放的是左括号Stack<Character> stack = new Stack<>();char[] chars = s.toCharArray();for(int i = 0; i < chars.length; i++){if(chars[i] == '[' || chars[i] == '(' || chars[i] == '{'){stack.push(chars[i]);}else{if(stack.empty()){//右括号多了return false;}else{if((chars[i] == '}' && stack.peek() == '{') || (chars[i] == ']' && stack.peek() == '[') || (chars[i] == ')' && stack.peek() == '(')){stack.pop();}else{//括号不匹配return false;}}}}if(!stack.empty()){//右括号多了return false;}return true;}
最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。
private Stack<Integer> stack;private Stack<Integer> minStack;public MinStack() {stack = new Stack<>();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(!minStack.empty()){if(popVal == minStack.peek()){minStack.pop();}}}public int top() {return stack.peek();}public int getMin() {return minStack.peek();}
相关文章:

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

某餐厅系统网络故障分析案例
背景 针对食堂经营企业,某堂食软件为客户提供优化堂食就餐流程、提高食堂服务水平和管理效率。 某上海客户使用该堂食系统,在就餐高峰时段,总是出现支付、点餐等操作缓慢,动辄一个操作需要等待几十秒。该客户联系软件厂商&#…...

华为OD机试题,用 Java 解【密室逃生游戏】问题
最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…...
如何重命名SQL Server数据库
重命名SQL Server数据库 使用T-SQL重命名SQL Server数据库使用分离和附加重命名SQL Server数据库使用T-SQL查询分离和重新连接在SSMS中分离和重新连接通过SSMS重命名SQL Server数据库当使用SQL数据库很长一段时间时,你可能会遇到需要为数据库命名的情况。它可以用几种不同的方…...

联想昭阳E5-ITL电脑开机后绿屏怎么U盘重装系统?
联想昭阳E5-ITL电脑开机后绿屏怎么U盘重装系统?有用户电脑正常开机之后,出现了屏幕变成绿屏,无法进行操作的情况。这个问题是系统出现了问题,那么如何去进行问题的解决呢?接下来我们一起来分享看看如何使用U盘重装电脑…...

车载开发知识交流【学习路线】
前言 在2023国内百废待兴;经济复苏的号召一直在响应,这对于压抑了三年的人民来说无疑是福音。这篇我们主要说一下拉动经济的其中大板块——车企;我们知道我们最大的经济除了房地产,第二就是车企。而在造车领域中也不断的加入了许…...

【读书笔记】《深入浅出数据分析》第二章 检验你的理论
文章目录一,相关分析方法1,相关系数二,相关性不等于因果关系三,证明因果关系,“控制变量法”?本章主要说明了两个问题: 1,相关性不等于因果关系 2,如何判断两种数据之间是相关性&am…...
pyflink学习笔记(一):table_apisql
具体定义请参考官方文档:https://nightlies.apache.org/flink/flink-docs-release-1.16/zh/docs/dev/table/overview/本文主要针对实际使用中比较常用的api进行整理,大多数例子都是官网,如有歧义可与官方对照。一、 创建 TableEnvironmentTab…...
GCC 编译器套件说明
写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。 目录GCC 简述GCC 主要…...

IDEA集成Git
1:IDEA集合Git1.1:配置Git忽略文件-IDEA特定文件问题 1:为什么要忽略他们?答: 与项目的实际功能无关, 不参与服务器上部署运行。把它们忽略掉能够屏蔽 IDE 工具之间的差异。问题 2:怎么忽略?1&a…...
算法流程图
里程计定位: 优:定位信息连续,无离散的跳跃 缺:存在累计误差,不利于长距或长期定位 传感器定位: 优:比里程计定位更精准 缺:会出现跳变情况,且传感器定位在标志物较少的环…...

Java中安装JDK环境–javac命令无效
Java中安装JDK环境–javac命令无效 一,安装JDK1.8 阿里云盘地址推荐 我们可以选择安装地址,这个地址是我们用来配置环境变量的,唯一注意的是这个,其他的都是默认下一步。直至安装完成,jdk下载地址https://www.oracl…...
递推问题
递推:在面对一个大任务的时候,有时候我们可以将大任务划分为小任务,再将小任务划分为更小的任务......,直到遇到初始情况,最后由初始情况一直往前推进,最后解决大任务,这就是递推的思想。递推问…...
js中强制类型转换Number、parseInt、parseFloat、Boolean、String、toString的使用
文章目录一、Number() 转换为整数二、Number.parseInt() 将字符串转换为整数三、Number.parseFloat() 将字符串转换为浮点数四、Boolean() 转换为布尔值五、String() 转换为字符串六、.toString() 转换为字符串最近在巩固 js 的基础知识,今天复习到了 js 中的数据类…...

漏斗分析法
一什么是漏斗分析? 漏斗分析是数据领域最常见的一种“程式化”数据分析方法,它能够科学地评估一种业务过程,从起点到终点,各个阶段的转化情况。通过可以量化的数据分析,帮助业务找到有问题的业务环节,并进…...
pycharm入门快捷操作(部分)
altenter:提示意图动作shift两次或者crtlshifta:查找框(查找动作、类、项目等)crtlw:一次一个字符、两次整个字符串(if条件下选择整个判断体)、三次整个句子、四次整个引用ctrlshiftw࿱…...

宣布 Databricks 支持 Amazon Graviton2,性价比提高3倍
今天,我们很高兴地宣布 Databricks 对基于 Amazon Graviton2 的亚马逊弹性计算云(Amazon EC2)实例的支持的公开预览。Graviton 处理器由亚马逊云科技进行定制设计和优化,为运行在 Amazon EC2 上的云工作负载提供最佳性价比。当与高…...

18_FreeRTOS任务通知
目录 任务通知的简介 任务通知值的更新方式 任务通知的优势 任务通知的劣势 任务通知值和通知状态 发送通知相关API函数 接收通知相关API函数 任务通知模拟信号量实验 任务通知模拟消息邮箱实验 任务通知模拟事件标志组实验 任务通知的简介 任务通知:用来通知任务的…...

【华为OD机试模拟题】用 C++ 实现 - 整理扑克牌(2023.Q1)
最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...

mysql lesson1
常用命令 1:exit 退出mysql 2:uroot pENTER键,再输入密码,不被别人看见 3:完美卸载:双击安装包,手动删除program file中的mysql,手动删除Programedate里的mysql 4:use mysql 使用数据库 5:…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...

PH热榜 | 2025-06-08
1. Thiings 标语:一套超过1900个免费AI生成的3D图标集合 介绍:Thiings是一个不断扩展的免费AI生成3D图标库,目前已有超过1900个图标。你可以按照主题浏览,生成自己的图标,或者下载整个图标集。所有图标都可以在个人或…...

JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除
目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作…...