数据结构——栈的实现(java实现)与相应的oj题

文章目录

  • 一 栈
    • 栈的概念:
    • 栈的实现:
    • 栈的数组实现
        • 默认构造方法
        • 压栈
        • 获取栈元素的个数
        • 出栈
        • 获取栈顶元素
        • 判断当前栈是否为空
    • java提供的Stack类
      • Stack实现的接口:
    • LinkedList也可以当Stack使用
    • 虚拟机栈,栈帧,栈的三个概念
  • 二 栈的一些算法题:
    • (1) 逆序打印单链表。
    • (2)[括号匹配](https://leetcode-cn.com/problems/valid-parentheses)
    • (3)[逆波兰表达式求值](https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/)
      • 逆波兰表达式
    • (4) [出入栈次序匹配](https://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId=13&&tqId=11174&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking)
    • (5)[最小栈](https://leetcode-cn.com/problems/min-stack/)
    • 总结:


一 栈

栈的概念:

栈也是一种线性表,栈只允许在表的一端进行插入与删除操作,所以栈中数据的特征的先进后出(先进来的后出去)。
栈顶:是栈进行插入与删除操作的表的一端
栈底:不允许插入删除操作的一端
压栈:将数据插入到栈中
出栈:将数据移除栈
在这里插入图片描述

栈的实现:

栈的底层可以由数组实现,也可以由链表实现
栈由数组实现时,栈的压栈与出栈的时间复杂度均为O(1)。
栈由单链表实现时,
如果采用尾插法,压栈操作时间复杂度为O(n),如果有last指针,则
压栈时间复杂度为O(1),但是出栈的时间复杂度一定为O(n)。
如果采用头插法,则压栈与出栈的时间复杂度均为O(1).
栈由双链表实现时,不论采用头插法与尾插法,时间复杂度均为O(1)。

栈的数组实现

当栈使用数组实现时,栈的插入与删除操作,时间复杂度均为O(1);

public class MyStack {static   int  DEFAULT_SIZE  = 10; //设置默认的数组大小private   int [] element ;        //实现栈的数组int usedsize = 0 ;                //栈中有效元素的个数//默认构造方法public MyStack() {}//入栈public void push(int val) {}//出栈public int pop() {}//获取栈顶元素 但是不删除public int peek() { }//获取栈元素个数public int size(){} //判空public boolean isEmpty() { }       
}
默认构造方法

默认申请10个空间

public MyStack(){this.element = new int[10];}
压栈

思想:先判断栈满没满,如果满了则扩容,然后进行压栈

  public void push(int data){//先判断栈是否有空间if(usedsize==element.length){//如果没有空间//则扩容this.element = Arrays.copyOf(element,2*element.length);}//保证空间后this.element[usedsize++] = data;}
获取栈元素的个数

思想:直接返回usedsize

 public int size(){return usedsize;}
出栈

思想:先判断栈是否为空,为空则抛出异常,不为空,则返回栈顶元素值,并且usedsize-1.

  public int pop(){//要判断栈是否为空,如果为空,则退出try{if (isEmpty()) {//2. 问题出现,构造参数的形参问题,super()调用父类的构造方法throw new EmptyException("EmptyException异常报错");}}catch (EmptyException e){e.printStackTrace();}int val =   this.element[usedsize-1];usedsize -- ;return val;}
获取栈顶元素

思想:与出栈逻辑相同,只是usedsize值不需-1 。

 public int  peek(){try{if (isEmpty()) {throw new EmptyException("EmptyException异常报错");}}catch (EmptyException e){e.printStackTrace();}return    this.element[usedsize-1];}
判断当前栈是否为空

思想:直接判断usedsize 是否为0即可。

 public boolean isEmpty(){return usedsize == 0;}

java提供的Stack类

在这里插入图片描述

Stack实现的接口:

在这里插入图片描述

  接口说明   1.  继承Cloneable接口支持克隆其他接口,暂时还没搞明白,以后更新补充

LinkedList也可以当Stack使用

java提供的LinkedList类也可以当做栈来使用,LinkedList的方法列表如下:
在这里插入图片描述

public class Test {public static void main(String[] args) {LinkedList<Integer> stack =  new LinkedList<>();stack.push(5);stack.push(2);stack.pop();stack.pop();stack.pop();}
}

在这里插入图片描述

虚拟机栈,栈帧,栈的三个概念

虚拟机栈是JVM中的一块内存。
栈帧是为一个方法,函数分配的内存。
栈是一种数据结构。

二 栈的一些算法题:

(1) 逆序打印单链表。

采用递归的方法:

// 递归方式
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 + " ");}
}

(2)括号匹配

题解:1 . 对于这个题无法直接看出其数学模型,必须先画图,列出各种情况,再判断
在这里插入图片描述
从图中可以分析出,要实现判断括号匹配

  1. 就要使得每一个左括号和右括号能够与对应位置的右括号进行匹配判断
  2. 且当所有的左括号(右括号)判断完时,其对应的右括号(左括号)也判断完毕,即满足左括号个数与右括号个数相当的情况。
  3. 如果第一个括号是右括号,说明此括号没有对应的左括号,说明一定为字符串一定括号不匹配。

实现思想:遍历字符串,遇到左括号则存入栈中,遇到右括号则与栈顶元素比较,相匹配,则继续循环,如果不匹配或栈为空,则返回false。

class Solution1 {public boolean isValid(String s) {Stack <Character> stack = new Stack<>();//采用for循环,这样可以找到字符串中的字符for(int i =0;i<s.length();i++) {char ch = s.charAt(i);if (ch == '{' || ch == '[' || ch == '(') {//问题,java提供的栈是否需要手动扩容?stack.push(ch);} else {//如果是右括号的内容if (stack.isEmpty()) {return false;} else {char ch2 = stack.peek();   //当获取栈顶元素时,栈可能为空//栈区不能为空if (((ch == '}' && ch2 == '{') || (ch == ']' && ch2 == '[') || (ch == ')' && ch2 == '('))) {//说明匹配,//将栈顶的元素去除stack.pop();} else {//如果不匹配,情况1 如果栈中还没有左括号,则一定不匹配,return false;}}}}// 如果栈表为空,说明匹配完毕if(stack.isEmpty()){return true;}return false;}
}

(3)逆波兰表达式求值

逆波兰表达式

逆波兰表达式即后缀表达式,后缀表达式是由中缀表达式转换而成。
所谓中缀表达式即我们平常所写的±*/的算式
我们平常所写的中缀表达式中是有优先级的,即先乘除,后加减,有括号先算括号里面的
但是计算机是不能够识别优先级的,为了能够使计算机计算,我们将中缀表达式的规则
表达成后缀表达式的形式,这样计算机便能够计算算式。

中缀表达式转换成后缀表达式的的规则:

  1. 先将中缀表达式中能够加括号的部分都加上括号
  2. 然后将所有的运算符移到所在 最近扩号之外。
  3. 然后去除掉所有括号即得到后缀表达式。

后缀表达式的运算规则:
遍历整个表达式,遇到运算符时,则将运算符前面的两个数作为操作数计算
得出的结果替代两个操作数,然后继续遍历表达式,循环上次操作。

在这里插入图片描述
本题:只是要求按照后缀表达式的规则计算结果
实现思想:遍历表达式,遇到操作数即将操作数压入栈中,遇到运算符,则进行两次出栈
,获取两个操作数进行计算(需要注意的是第一次出栈的是右操作数,第二次出栈的是左操作数)
然后将计算的结果再进行压栈,然后循环此操作。

class Solution {public int evalRPN(String[] tokens) {//创建一个栈,创建栈时不需要考虑栈的空间大小Stack<Integer> stack = new Stack<>();//采用foreach进行遍历栈for (String str : tokens) {if (!isOperator(str)) {int a = Integer.parseInt(str);stack.push(a);} 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.peek();}

总结
1. 字符串形式的运算符不能直接转换成运算符
2. 后缀表达式先进栈的是左操作数,后进栈的是右操作数,当我们需要出栈时,第一次获取栈顶元素是右操作数,第二次获取栈顶元素才是左操作数。

(4) 出入栈次序匹配

在这里插入图片描述

class Solution2{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() && j < popV.length &&stack.peek() == popV[j]) {stack.pop();j++;}}return stack.empty();}
}

(5)最小栈

题解:
如果只用一个栈的话,我们不可能实现题目的要求,只有能将栈的最小值时刻储存起来才能实现题目的要求。因此我们实现两个栈,一个栈用于存储数据,另一个最小栈用于存放栈当前的最小值。

在这里插入图片描述实现思想:入栈的规则:

  1. 普通栈一定要放,最小栈如果为空,或者栈顶元素小于压入的数据,则放入最小栈中
  2. 如果压入的数据与最小栈栈顶元素相当,也放入最小栈中。(因为最小栈中的元素必须与普通栈的最小值保持同步即必须与出栈的规则相匹配)。
    出栈的规则:
    如果普通栈的栈顶元素与最小栈栈顶元素相同,则最小栈也需要出栈。
class MinStack {//创建两个栈Stack <Integer> stack  =  new Stack<>(); //普通栈Stack <Integer> minStack = new Stack<>();//最小栈public MinStack() {}
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 val =  stack.pop();//最小栈出栈://如果两栈的栈顶元素相同,则出栈if(val == minStack.peek()){minStack.pop();}}public int top() {//获取栈顶元素if(!stack.empty()){return stack.peek();}return -1 ;}public int getMin() {if(minStack.empty()){return -1;}return minStack.peek();}}

总结:

在使用栈时,最常用的运用是根据栈先进后出的特性,将一段有序的数据转为逆序后,再进行操作使用。

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

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

相关文章

JetBrains IDE 使用git进行多人合作开发教程

以下DEMO可以用于多人共同开发维护一个项目时&#xff0c;使用Git远程仓库的实践方案 分支管理 dev&#xff1a;开发分支test&#xff1a;测试分支prod&#xff1a;生成分支 个人开发也最起码有一个masterdev&#xff0c;作为主分支和当前开发分支。master永远是稳定版本&am…

花几千上万学习Java,真没必要!(十九)

1、StringBuilder&#xff1a; 测试代码1&#xff1a; package stringbuilder.com; import java.util.ArrayList; import java.util.List; public class StringBuilderExample { public static void main(String[] args) { // 初始化StringBuilder StringBuilder sb n…

腾讯会议产品策划的成长之路:从万字文档到功能落地的实战经验

腾讯会议产品策划的成长之路&#xff1a;从万字文档到功能落地的实战经验 在腾讯会议的产品团队中&#xff0c;有这样一位产品策划&#xff0c;他以其出色的逻辑思维、全局观念以及扎实的执行力&#xff0c;在团队中发挥着举足轻重的作用。他就是林陪同&#xff0c;一个自称“会…

JAVA进阶学习12

文章目录 一、File类1.1 File对象的构造1.2 File对象的常见方法判断功能的方法获取功能的方法绝对路径和相对路径创建删除功能的方法 1.3 File的常用遍历方法1.4 File获取并遍历的其他方法1.5 用法举例二、IO流2.1 IO的分类2.2 字节流的方法概述2.2.1 FileOutputStream2.2.2 Fi…

UE4-字体导入

一.字体导入 方法一&#xff1a; 然后通过导入将自己想要的字体导入到项目中&#xff0c;也可以直接将我们放在桌面的字体直接拖入到我们的内容浏览器中。 但是要注意想要发售游戏的话不可以这样导入微软的字体&#xff0c;因为Windows自带基本都有版权&#xff0c;所以最…

明星应援系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;线上应援管理&#xff0c;线下应援管理&#xff0c;应援物品管理&#xff0c;购买订单管理&#xff0c;集资应援管理&#xff0c;集资订单管理&#xff0c;市集订单管理&#xff0…

【CSS in Depth 2 精译_020】3.3 元素的高度

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

在 CI/CD 中怎么使用 Docker 部署前端项目?

本项目代码已开源&#xff0c;具体见&#xff1a; 前端工程&#xff1a;vue3-ts-blog-frontend 后端工程&#xff1a;express-blog-backend 数据库初始化脚本&#xff1a;关注公众号程序员白彬&#xff0c;回复关键字“博客数据库脚本”&#xff0c;即可获取。 前言 在上一篇文…

快速上手AI指令:打造个性化智能交互体验的全面指南

快速上手AI指令&#xff1a;打造个性化智能交互体验的全面指南 一、初识文心一言1.1 文心一言简介1.2 文心一言的特点 二、准备工作2.1 获取访问权限2.2 熟悉界面布局2.3 了解基础指令 三、基础指令操作3.1 问答互动3.2 文本创作3.3 任务规划 四、进阶指令操作4.1 复杂查询4.2 …

Python酷库之旅-第三方库Pandas(035)

目录 一、用法精讲 106、pandas.Series.iloc方法 106-1、语法 106-2、参数 106-3、功能 106-4、返回值 106-5、说明 106-6、用法 106-6-1、数据准备 106-6-2、代码示例 106-6-3、结果输出 107、pandas.Series.__iter__魔法方法 107-1、语法 107-2、参数 107-3、…

Java程序的故障排查

文章目录 Linux命令关机/重启/注销系统信息和性能查看磁盘和分区⽤户和⽤户组⽹络和进程管理常⻅系统服务命令⽂件和⽬录操作⽂件查看和处理打包和解压RPM包管理命令YUM包管理命令DPKG包管理命令APT软件⼯具 JDK命令jpsjstatjinfojmapjhatjstackjcmdjconsole 分析工具VisualVME…

自动驾驶-预测概览

通过生成一条路径来预测一个物体的行为&#xff0c;在每一个时间段内&#xff0c;为每一辆汽车重新计算预测他们新生成的路径&#xff0c;这些预测路径为规划阶段做出决策提供了必要信息 预测路径有实时性的要求&#xff0c;预测模块能够学习新的行为。我们可以使用多源的数据…

超简单安装指定版本的clickhouse

超简单安装指定版本的clickhouse 命令执行shell脚本 idea连接 命令执行 参考官网 # 下载脚本 wget https://raw.githubusercontent.com/183461750/doc-record/d988dced891d70b23c153a3bbfecee67902a3757/middleware/data/clickhouse/clickhouse-install.sh # 执行安装脚本(中…

【漏洞复现】Netgear WN604 downloadFile.php 信息泄露漏洞(CVE-2024-6646)

0x01 产品简介 NETGEAR WN604是一款由NETGEAR&#xff08;网件&#xff09;公司生产的无线接入器&#xff08;或无线路由器&#xff09;提供Wi-Fi保护协议&#xff08;WPA2-PSK, WPA-PSK&#xff09;&#xff0c;以及有线等效加密&#xff08;WEP&#xff09;64位、128位和152…

亲测--linux下安装ffmpeg最新版本---详细教程

下载地址 Download FFmpeg 下载最新的https://ffmpeg.org/releases/ffmpeg-7.0.1.tar.xz 上传到服务器 解压 tar xvf ffmpeg-7.0.1.tar.xz 编译 cd ffmpeg-7.0.1 ./configure --prefix=/usr/local/ffmpeg make && make install 报错: 解决:在后面加 跳过检测…

【Word】——小技巧

1.PDF相关转换word PDF转换成Word在线转换器 - 免费 - CleverPDF 2. word插入公式 1.软件推荐&#xff08;免费&#xff09; 可直接将图片&#xff0c;截屏公式转为word标准规范形式 2.网址推荐 在线LaTeX公式编辑器-编辑器 &#xff08;每天有免费使次数&#xff09; 3.…

Matlab演示三维坐标系旋转

function showTwo3DCoordinateSystemsWithAngleDifference() clear all close all % 第一个三维坐标系 origin1 [0 0 0]; x_axis1 [1 0 0]; y_axis1 [0 1 0]; z_axis1 [0 0 1];% 绕 x 轴旋转 30 度的旋转矩阵 theta_x 30 * pi / 180; rotation_matrix_x [1 0 0; 0 cos(th…

Linux服务器配置Python+PyTorch+CUDA深度学习环境

参考博主 Linux服务器配置PythonPyTorchCUDA深度学习环境_linux cuda环境配置-CSDN博客 https://blog.csdn.net/NSJim/article/details/115386936?ops_request_misc&request_id&biz_id102&utm_termlinux%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83%E6%8C%89pytorch%20…

4核16G服务器支持多少人?4C16G服务器性能测评

租赁4核16G服务器费用&#xff0c;目前4核16G服务器10M带宽配置70元1个月、210元3个月&#xff0c;那么能如何呢&#xff1f;配置为ECS经济型e实例4核16G、按固定带宽10Mbs、100GB ESSD Entry系统盘。 那么问题来了&#xff0c;4C16G10M带宽的云服务器可以支持多少人同时在线&…

C++ ───List的使用

目录 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 1.2.6 list的迭代器失效 1.1 list的介绍 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&…