Java - 数据结构,栈

本文介绍了Java中的栈数据结构及其在Java虚拟机栈中的应用。讲解了栈的基本概念,如后进先出原则,以及Java虚拟机栈中的栈帧。还探讨了栈在面试中的常见笔试题,如中缀表达式转后缀表达式,并介绍了如何使用栈解决有效括号和设计最小栈的问题。
摘要由CSDN通过智能技术生成

一、栈

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;
        //遍历数组pushed
        for(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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Später321

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值