Java-----栈

news2024/11/15 13:35:20

目录

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.coloradmin.cn/o/1950951.html

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

相关文章

Centos8 yum 更换源以及安装内核头文件

文章目录 一、简介二、yum 更换源三、安装内核头文件 一、简介 CentOS 是一个开源项目&#xff0c;发布了两个不同的 Linux 发行版——CentOS Stream 和 CentOS Linux 。 CentOS Stream 是即将发布的红帽企业 Linux 产品的上游开发平台。 CentOS 项目将于 2024 年 6 月 30 日…

场外期权如何报价?名义本金是什么?

今天带你了解场外期权如何报价&#xff1f;名义本金是什么&#xff1f;投资者首先需要挑选自己想要进行期权交易的沪深上市公司股票。选出股票后&#xff0c;需要将股票信息、预期的操作时间&#xff08;如期限&#xff09;、看涨或看跌的选择以及预计的交易金额等信息报给场外…

商家虚假发货行为频发,电商平台如何通过物流轨迹来监管?(内附视频号、抖音、京东的发货规则)

近年来&#xff0c;“虚假发货”问题在电商行业中日益凸显。某投诉平台数据显示&#xff0c;截至2024年7月&#xff0c;搜索“虚假发货”显示的投诉高达19万条&#xff0c;如何有效监控卖家发货的合规性与及时性、打击虚假发货行为成为电商平台的重要议题。 为了维护消费者权益…

剧透:巴黎奥运会用上了AI转播

** AI增强技术&#xff0c;让比赛画面变成电影特效。 ** 巴黎奥运会即将开幕&#xff01; 阿里云在奥运转播中应用的AI增强技术 将让比赛画面变成电影特效&#xff01; 剧透如下 &#x1f447;&#x1f3fb; 阿里云为奥运转播提供的高自由度回放“子弹时间”&#xff0c;是…

[Mysql-DDL数据操作语句]

目录 DDL语句操作数据库 库&#xff1a; 查看&#xff1a;show 创建&#xff1a;creat 删除&#xff1a;drop 使用(切换)&#xff1a;use 表&#xff1a; 查看&#xff1a;desc show 创建&#xff1a;create 表结构修改 rename as add drop modify change rename as …

cesium海洋到站提示

项目地址:Every Admin: 用于快速搭建后台管理和其他页面的项目,组件化开发,以及大屏展示. <template> <div class"topbox"> xx海洋管理 </div> <div class"selectbox"> <div class"title"> 航线列表 </div>…

了解Java虚拟机(JVM)

前言&#x1f440;~ 上一章我们介绍网络原理相关的知识点&#xff0c;今天我们浅浅来了解一下java虚拟机JVM JVM&#xff08; Java Virtual Machine &#xff09; JVM内存区域划分 方法区/元数据区&#xff08;线程共享&#xff09; 堆&#xff08;线程共享&#xff09; 虚…

Nginx 配置与优化:常见问题全面解析

文章目录 Nginx 配置与优化:常见问题全面解析一、Nginx 安装与配置问题1.1 Nginx 安装失败问题描述解决方法1.2 Nginx 配置文件语法错误问题描述解决方法二、Nginx 服务启动与停止问题2.1 Nginx 无法启动问题描述解决方法2.2 Nginx 服务无法停止问题描述解决方法三、Nginx 性能…

尚硅谷vue全家桶(vue2+vue3)笔记

Vue2 一、Vue核心 01_简介 1.特点 采用组件化模式&#xff0c;提高代码复用率、且让代码更好维护。声明式编码&#xff0c;让编程人员无需直接操作DOM&#xff08;命令式编码&#xff09;&#xff0c;提高开发效率。使用虚拟DOM优秀的Diff算法&#xff0c;尽量复用DOM节点。…

【日常记录】【JS】JS中查询参数处理工具URLSearchParams

文章目录 1. 引言2. URLSearchParams2.1 URLSearchParams 的构造函数2.2 append() 方法2.3 delete() 方法2.4 entries() 方法2.5 forEach() 方法2.6 get() 方法2.7 getAll() 方法2.8 has() 方法2.9 keys() 方法2.10 set() 方法2.11 toString() 方法2.12 values() 方法 参考链接…

Pytorch深度学习实践(5)逻辑回归

逻辑回归 逻辑回归主要是解决分类问题 回归任务&#xff1a;结果是一个连续的实数分类任务&#xff1a;结果是一个离散的值 分类任务不能直接使用回归去预测&#xff0c;比如在手写识别中&#xff08;识别手写 0 − − 9 0 -- 9 0−−9&#xff09;&#xff0c;因为各个类别…

python毕业设计选题协同过滤算法在音乐推荐系统

✌网站介绍&#xff1a;✌10年项目辅导经验、专注于计算机技术领域学生项目实战辅导。 ✌服务范围&#xff1a;Java(SpringBoo/SSM)、Python、PHP、Nodejs、爬虫、数据可视化、小程序、安卓app、大数据等设计与开发。 ✌服务内容&#xff1a;免费功能设计、免费提供开题答辩P…

【进程检测】使用pywin32捕获window进程信息

需求 检测win系统依赖服务进程的运行情况&#xff0c;版本信息&#xff08;进程检测器&#xff09;检测内外网连接情况 实现 进程检测 # 使用pywin32获取进程版本信息 def get_version_info(path):try:info GetFileVersionInfo(path, \\)ms info[FileVersionMS]ls info[…

基于单片机控制的气动机械手设计

摘 要&#xff1a; 机械手拥有灵活的运动结构&#xff0c;可以在控制系统控制下完成复杂的运动&#xff0c;从而实现高效率的自动化生产方式&#xff0c;因而成为发展工业生产技术的重要方向。气动技术和单片机技术已相当成熟&#xff0c;工业应用广泛&#xff0c;该文将基于单…

使用 useRequestURL 组合函数访问请求URL

title: 使用 useRequestURL 组合函数访问请求URL date: 2024/7/26 updated: 2024/7/26 author: cmdragon excerpt: 摘要&#xff1a;本文介绍了Nuxt 3中的useRequestURL组合函数&#xff0c;用于在服务器端和客户端环境中获取当前页面的URL信息。通过示例展示了如何在页面中…

html+css 实现水波纹按钮

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

Vue 3 实现左侧列表点击跳转滚动到右侧对应区域的功能

使用 Vue 3 实现左侧列表点击跳转到右侧对应区域的功能 1. 引言 在这篇博客中&#xff0c;我们将展示如何使用 Vue 3 实现一个简单的页面布局&#xff0c;其中左侧是一个列表&#xff0c;点击列表项时&#xff0c;右侧会平滑滚动到对应的内容区域。这种布局在很多应用场景中都…

云计算实训15——shell脚本、变量、自动化安装脚本、条件判断、循环

一、shell 脚本 1.基本概念 shell脚本就是由Shell命令组成的执行文件&#xff0c;将一些命令整合到一个文件 中&#xff0c;进行处理业务逻辑&#xff0c;脚本不用编译即可运行&#xff0c;它从一定程度上减轻 了工作量&#xff0c;提高了工作效率&#xff0c;还可以批量、定…

云服务部署项目(Spring + Vue)

云计算&#xff1a;腾讯云 操作系统&#xff1a;Ubuntu 22.04.4 LTS 项目&#xff1a;若依前后端分离项目&#xff08;SpringBoot Vue&#xff09; 首先要安装基本的一些依赖环境&#xff0c;大家可以看一下我往期的文章&#xff1a; Ubuntu在线JDK Ubuntu在线安装Nginx Ubunt…

Debain安装PostgreSql

目录 Debian和Centos区别 安装PostgreSql 更新包索引&#xff1a; 安装 PostgreSQL&#xff1a; 配置自动启动和启用 PostgreSQL 服务&#xff1a; 配置postGreSql 切换到 PostgreSQL 用户&#xff1a; 访问 PostgreSQL Shell&#xff1a; 设置密码 退出 PostgreSQL …