【Java数据结构】栈 (Stack)

【本节目标】
1. 栈的概念及使用
2. 相关 OJ

一、概念

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

栈在现实生活中的例子:

二、栈的使用

 

 public static void main(String[] args) {Stack<Integer> s = new Stack();s.push(1);s.push(2);s.push(3);s.push(4);System.out.println(s.size()); // 获取栈中有效元素个数---> 4System.out.println(s.peek()); // 获取栈顶元素---> 4s.pop(); // 4出栈,栈中剩余1 2 3,栈顶元素为3System.out.println(s.pop()); // 3出栈,栈中剩余1 2 栈顶元素为3if(s.empty()){System.out.println("栈空");}else{System.out.println(s.size());}}

三、栈的模拟实现

从上图中可以看到, Stack 继承了 Vector Vector ArrayList 类似,都是动态的顺序表,不同的是 Vector 是线程安全的。

import java.sql.Array;
import java.util.Arrays;public class MyStack {public int[] elem;public int usedSize;public MyStack(int[] elem) {this.elem = new int[10];}public void push(int data){if(ifFull()){grow();}elem[usedSize++]=data;}public boolean ifFull(){return elem.length==usedSize;}private void grow(){elem= Arrays.copyOf(elem,elem.length*2);}public int pop(){if(isEmpty()){throw new  EmptyException("栈为空");}else {int k=usedSize-1;usedSize--;return elem[k];}}private boolean isEmpty(){return usedSize==0;}public int peek(){if(isEmpty()){throw new  EmptyException("栈为空");}else {return elem[usedSize-1];}}
}

四、栈的应用场景

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

单链表是否可以实现栈?

答:

  • 顺序表实现的栈可以将插入、删除的时间复杂度达到O(1),
  • 如果采用尾插操作,入栈时间复杂度为O(N),如果有last那么时间复杂度为O(1),但是出栈一定是O(N)
  • 如果采用头插法,入栈时间复杂度为O(1),同时出栈的时间复杂度也是O(1)

结论:

  • 如果采用单链表来实现栈,那么可以采用头插法的形式来入栈和出栈,叫做链式栈
  • 采用双向链表来实现栈是完全ok的,入栈不管是头插还是尾插都可以实现,时间复杂度都可以达到O(1)

2. 将递归转化为循环

比如:逆序打印链表

{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. 括号匹配

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((ch2=='('&&ch==')')||(ch2=='['&&ch==']')||(ch2=='{'&&ch=='}')){stack.pop();//有括号刚好匹配左括号,出栈}else{return false;//右括号不匹配左括号,错误}}}if(!stack.isEmpty()){return false;//遍历结束但是但是栈不空,左括号多}return true;}
}

4. 逆波兰表达式求值

题目:中缀表达式a+b*c+(d*e+f)*g,其转换成后缀表达式为abc*+de*f+g*+。

将表达式按照运算先后加括号

a+b*c+(d*e+f)*g=a+b*c+(d*e+f)*g

再将每个运算符移出对应的括号外面

a+b*c+(d*e+f)*g)=(abc*+(de*f)+g*+

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

把字符串变成整形的函数Integer.parseInt() 

5. 出栈入栈次序匹配

顺序遍历pushV,如果栈顶元素和popV当前元素相同,则弹出,不同则将pushV当前元素入栈

import java.util.*;
public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param pushV int整型一维数组 * @param popV int整型一维数组 * @return bool布尔型*/public boolean IsPopOrder (int[] pushV, int[] popV) {// write code hereStack<Integer> stack=new Stack<>(); int j=0;for(int i=0;i<pushV.length;i++){stack.push(pushV[i]);while(stack.empty()==false&&j<popV.length&&stack.peek()==popV[j]){stack.pop();j++;}}return stack.empty();}
}

6. 最小栈

入栈:

  • 普通栈一定要放
  • 最小栈放的原则:
    • 如果最小栈是空的,则放
    • 如果放的元素小于等于当前栈顶的元素,则放

出栈:判断出栈元素和最小栈栈顶元素关系,相同则最小栈也出去

import java.util.Stack;class MinStack {public Stack<Integer> stack;public  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 {int peekVal = minStack.peek();if(val <= peekVal) {minStack.push(val);}}}public void pop() {if(stack.empty()) {return;}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();}
}

五、 概念区分

栈、虚拟机栈、栈帧有什么区别呢?
  • 栈:是一种数据结构
  • 虚拟机栈:是jvm中的一块内存
  • 栈帧:运行一个方法、一个函数时,给它开辟的内存

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

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

相关文章

Vue项目中通过插件pxtorem实现大屏响应式

一、原理 rem单位代表的是根节点的font-size大小&#xff0c;所以当我们在页面上使用rem去替代px的时候&#xff0c;就可以通过修改根节点font-size的值&#xff0c;动态地让页面上的元素根据不同浏览器宽高下去实现变化。 二、工具 1.postcss-pxtorem 作用&#xff1a;在编…

OpenAI Sora如何使用?

引言&#xff1a;OpenA推出首款AI视频模型Sora&#xff0c;震惊世界&#xff01; Sora是什么&#xff1f; Sora是OpenAI最新发布的文本生成视频&#xff08;Text to Video&#xff09;大模型&#xff0c;能生成长达60秒的视频 Sora能够创造出包括多个角色、特定动作类型以及…

10个令人惊叹的AI工具

AI 确实改变了游戏规则&#xff1b;它彻底改变了我们工作、创造和与技术互动的方式。虽然 ChatGPT、DALLE 和 Midjourney 等巨头占据了大部分头条新闻&#xff0c;但还有很多其他不为人知的 AI 工具和技术&#xff0c;大多数都同样令人惊叹。 以下是十种你可能没有听说过但绝对…

6个最受欢迎的大模型本地运行工具

运行大型语言模型 (LLM)&#xff08;如 ChatGPT 和 Claude&#xff09;通常涉及将数据发送到 OpenAI 和其他 AI 模型提供商管理的服务器。虽然这些服务是安全的&#xff0c;但一些企业更愿意将数据完全离线&#xff0c;以保护更大的隐私。 本文介绍了开发人员可以用来在本地运…

codetop标签动态规划大全C++讲解(二)!!动态规划刷穿地心!!学吐了家人们o(╥﹏╥)o

一篇只有十题左右&#xff0c;写少一点好复习 1.目标和2.分割等和子集3.完全平方数4.比特位计数5.石子游戏6.预测赢家7.不同的二叉搜索树8.解码方法9.鸡蛋掉落10.正则表达式匹配11.通配符匹配12.交错字符串 1.目标和 给你一个非负整数数组 nums 和一个整数 target 。 向数组中…

WindowsTerminal 美化-壁纸随机更换

目录 一. 相关网址二. 壁纸随机更换思路三. 指定 WindowsTermina 壁纸路径四. 编写脚本&#xff0c;随机替换壁纸4.1 powershell脚本4.2 .bat批处理脚本 四. 配置定时任务&#xff0c;添加触发器五. 效果 一. 相关网址 官方下载 Windows Terminal 官方Github微软商店 美化 Oh …

力扣之1285.找到连续区间的开始和结束

题目 sql建表语句&#xff1a; Create table If Not Exists Logs (log_id int); Truncate table Logs; insert into Logs (log_id) values (1); insert into Logs (log_id) values (2); insert into Logs (log_id) values (3); insert into Logs (log_id) values (7); inse…

白板2-数学基础

高斯分布1-极大似然估计 高斯分布2-极大似然估计-无偏&有偏 高斯分布3-从概率密度角度高斯分布4-局限性高斯分布5-边缘概率及条件概率高斯分布6-求联合概率分布

基于SpringBoot vue 医院病房信息管理系统设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…

DELL SC compellent存储的四种访问方式

DELL SC存储&#xff08;国内翻译为 康贝存储&#xff0c;英文是compellent&#xff09;, compellent存储是dell在大概10多年前收购的一家存储&#xff0c;原来这个公司就叫做compellent。 本文的阅读对象是第一次接触SC存储的技术朋友们&#xff0c;如何访问和管理SC存储。总…

一条广告变现3W+,半个月涨粉30W!简直太香了!

今天给大家分享个变现很猛的赛道&#xff0c; 这个赛道&#xff0c;我一开始关注到的时候&#xff0c;是一两个月前吧&#xff0c; 当时看到的时候&#xff0c;相关的笔记流量很猛&#xff0c; 而且相关的账号&#xff0c;起的号也很多&#xff0c; 我当时是看到那么多人都…

《数据结构》--栈【概念应用、图文并茂】

本节讲完栈下次再讲一下队列&#xff0c;最后补充一个串&#xff0c;我们的线性结构基本就完事了。下图中黄色框框圈中的是我们今日份内容(分为两篇博客)&#xff1a; 知识体系图 栈(Stack-LIFO)结构 栈的基础概念 栈(Stack)是一个后进先出(Last-In-First-Out)的一个特殊数据…

五种IO模型与阻塞IO

一、前言 在网络中通信的本质其实是网络中的两台主机的进程间进行通信&#xff0c;而进程通信的本质就是IO。 IO分为输入&#xff08;input&#xff09;和输出&#xff08;output&#xff09;站在进程的角度讲&#xff0c;进程出去数据为输出&#xff0c;外部数据进入进程为输…

ubunut声卡配置 播放视频没有声音的解决方法 alsamixer和pavucontrol的使用方法

文章目录 &#x1f319;ubuntu22.04网页没有声音&#xff0c;声卡提示Dummy Output&#x1f319;方法一&#xff1a;切换内核&#x1f319;方法二&#xff1a;使用知乎的方法 &#x1f319;ubuntu22.04 连接蓝牙耳机&#xff0c;1秒后断连解决方法ubuntu声音操作alsamixerpavuc…

边缘计算插上AI的翅膀会咋样?

人工智能&#xff08;Artificial Intelligence,AI&#xff09;是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学&#xff0c;是新一轮产业革命的重要驱动力量。2022年底发布的ChatGPT将人工智能技术上升到了一个新的高度。如今&#x…

17岁孩子开发AI应用,4个月入百万,人人都是AI产品经理的时代快来了

随着AI时代的到来叠加经济下行&#xff0c;越来越多的独立开发者梦想着实现年入百万的壮举。 近日&#xff0c;这种小概率事件正在发生。 17岁高中生做了个AI APP&#xff0c;短短四个月销售额达100 万美元。 小伙儿Zach Yadegari&#xff08;下面暂称小扎克&#xff09;在X…

用IMX6UL开发板编写按键输入实验

在之前我们都是讲解如何使用IMX6UL的GPIO输出控制等功能&#xff0c;IMX6U的IO不仅能作为输出&#xff0c;而且也可以作为输入&#xff0c;而我们开发板上具有一个按键&#xff0c;按键肯定是连接了一个IO口的额&#xff0c;我们在这一节将会把IO配置成输入功能&#xff0c;读取…

codetop标签动态规划大全C++讲解(三)!!动态规划刷穿地心!!学吐了家人们o(╥﹏╥)o

每天复习一篇&#xff0c;只有十题左右 1.买卖股票的最佳时机2.买卖股票的最佳时机含手续费3.买卖股票的最佳时机III4.买卖股票的最佳时机IV5.打家劫舍6.打家劫舍II7.不同路径8.不同路径II9.最小路径和10.三角形的最小路径和11.两个字符串的删除操作12.编辑距离13.一和零 1.买卖…

强化学习笔记之【DDPG算法】

强化学习笔记之【DDPG算法】 文章目录 强化学习笔记之【DDPG算法】前言&#xff1a;原论文伪代码DDPG算法DDPG 中的四个网络代码核心更新公式 前言&#xff1a; 本文为强化学习笔记第二篇&#xff0c;第一篇讲的是Q-learning和DQN 就是因为DDPG引入了Actor-Critic模型&#x…

Ubuntu22.04 Docker 国内安装最靠谱教程

目前docker在国内安装常存在众所周知的网络问题&#xff0c;如果安装过程如果从官网地址安装以及安装之后从官网要拉取镜像都存在问题。这篇文章主要针对这两个问题总结最靠谱的docker安装教程。 1. docker安装 1.1 系统环境概述 Ubuntu 22.04linux内核版本 6.8&#xff08;…