【数据结构-栈】栈基础

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
    • 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

    • 一.栈介绍
      • 1.概述
      • 2.链表实现
      • 3.数组实现
      • 4.应用
    • 二.栈题目
      • 1.有效的括号-力扣 20 题
      • 2.后缀表达式求值-力扣 120 题
      • 3.中缀表达式转后缀
      • 4.双栈模拟队列-力扣 232 题
      • 5.单队列模拟栈-力扣 225 题

一.栈介绍

1.概述

计算机科学中,stack 是一种线性的数据结构,只能在其一端添加数据和移除数据。习惯来说,这一端称之为栈顶,另一端不能操作数据的称之为栈底,就如同生活中的一摞书

先提供一个栈接口

public interface Stack<E> {/*** 向栈顶压入元素* @param value 待压入值* @return 压入成功返回 true, 否则返回 false*/boolean push(E value);/*** 从栈顶弹出元素* @return 栈非空返回栈顶元素, 栈为空返回 null*/E pop();/*** 返回栈顶元素, 不弹出* @return 栈非空返回栈顶元素, 栈为空返回 null*/E peek();/*** 判断栈是否为空* @return 空返回 true, 否则返回 false*/boolean isEmpty();/*** 判断栈是否已满* @return 满返回 true, 否则返回 false*/boolean isFull();
}

2.链表实现

public class LinkedListStack<E> implements Stack<E>, Iterable<E> {private final int capacity;private int size;private final Node<E> head = new Node<>(null, null);public LinkedListStack(int capacity) {this.capacity = capacity;}@Overridepublic boolean push(E value) {if (isFull()) {return false;}head.next = new Node<>(value, head.next);size++;return true;}@Overridepublic E pop() {if (isEmpty()) {return null;}Node<E> first = head.next;head.next = first.next;size--;return first.value;}@Overridepublic E peek() {if (isEmpty()) {return null;}return head.next.value;}@Overridepublic boolean isEmpty() {return head.next == null;}@Overridepublic boolean isFull() {return size == capacity;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {Node<E> p = head.next;@Overridepublic boolean hasNext() {return p != null;}@Overridepublic E next() {E value = p.value;p = p.next;return value;}};}static class Node<E> {E value;Node<E> next;public Node(E value, Node<E> next) {this.value = value;this.next = next;}}
}

3.数组实现

public class ArrayStack<E> implements Stack<E>, Iterable<E>{private final E[] array;private int top = 0;@SuppressWarnings("all")public ArrayStack(int capacity) {this.array = (E[]) new Object[capacity];}@Overridepublic boolean push(E value) {if (isFull()) {return false;}array[top++] = value;return true;}@Overridepublic E pop() {if (isEmpty()) {return null;}return array[--top];}@Overridepublic E peek() {if (isEmpty()) {return null;}return array[top-1];}@Overridepublic boolean isEmpty() {return top == 0;}@Overridepublic boolean isFull() {return top == array.length;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {int p = top;@Overridepublic boolean hasNext() {return p > 0;}@Overridepublic E next() {return array[--p];}};}
}

4.应用

模拟如下方法调用

public static void main(String[] args) {System.out.println("main1");System.out.println("main2");method1();method2();System.out.println("main3");
}public static void method1() {System.out.println("method1");method3();
}public static void method2() {System.out.println("method2");
}public static void method3() {System.out.println("method3");
}

模拟代码

public class CPU {static class Frame {int exit;public Frame(int exit) {this.exit = exit;}}static int pc = 1; // 模拟程序计数器 Program counterstatic ArrayStack<Frame> stack = new ArrayStack<>(100); // 模拟方法调用栈public static void main(String[] args) {stack.push(new Frame(-1));while (!stack.isEmpty()) {switch (pc) {case 1 -> {System.out.println("main1");pc++;}case 2 -> {System.out.println("main2");pc++;}case 3 -> {stack.push(new Frame(pc + 1));pc = 100;}case 4 -> {stack.push(new Frame(pc + 1));pc = 200;}case 5 -> {System.out.println("main3");pc = stack.pop().exit;}case 100 -> {System.out.println("method1");stack.push(new Frame(pc + 1));pc = 300;}case 101 -> {pc = stack.pop().exit;}case 200 -> {System.out.println("method2");pc = stack.pop().exit;}case 300 -> {System.out.println("method3");pc = stack.pop().exit;}}}}
}

二.栈题目

1.有效的括号-力扣 20 题

一个字符串中可能出现 [] (){} 三种括号,判断该括号是否有效

有效的例子

()[]{}([{}])()

无效的例子

[)([)]([]

思路

  • 遇到左括号, 把要配对的右括号放入栈顶
  • 遇到右括号, 若此时栈为空, 返回 false,否则把它与栈顶元素对比
    • 若相等, 栈顶元素弹出, 继续对比下一组
    • 若不等, 无效括号直接返回 false
  • 循环结束
    • 若栈为空, 表示所有括号都配上对, 返回 true
    • 若栈不为空, 表示右没配对的括号, 应返回 false

答案(用到了课堂案例中的 ArrayStack 类)

public boolean isValid(String s) {ArrayStack<Character> stack = new ArrayStack<>(s.length() / 2 + 1);for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == '(') {stack.push(')');} else if (c == '[') {stack.push(']');} else if (c == '{') {stack.push('}');} else {if (!stack.isEmpty() && stack.peek() == c) {stack.pop();} else {return false;}}}return stack.isEmpty();
}

2.后缀表达式求值-力扣 120 题

后缀表达式也称为逆波兰表达式,即运算符写在后面

  • 从左向右进行计算
  • 不必考虑运算符优先级,即不用包含括号

示例

输入:tokens = ["2","1","+","3","*"]
输出:9
即:(2 + 1) * 3输入:tokens = ["4","13","5","/","+"]
输出:6
即:4 + (13 / 5)

题目假设

  • 数字都视为整数
  • 数字和运算符个数给定正确,不会有除零发生

代码

public int evalRPN(String[] tokens) {LinkedList<Integer> numbers = new LinkedList<>();for (String t : tokens) {switch (t) {case "+" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a + b);}case "-" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a - b);}case "*" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a * b);}case "/" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a / b);}default -> numbers.push(Integer.parseInt(t));}}return numbers.pop();
}

3.中缀表达式转后缀

#反编译可以看到执行指令的过程
javap -c -v .\E03InfixToSuffix.class
public class E03InfixToSuffix {/*思路1. 遇到数字, 拼串2. 遇到 + - * /- 优先级高于栈顶运算符 入栈- 否则将栈中高级或平级运算符出栈拼串, 本运算符入栈3. 遍历完成, 栈中剩余运算符出栈拼串- 先出栈,意味着优先运算4. 带 ()- 左括号直接入栈- 右括号要将栈中直至左括号为止的运算符出栈拼串|   ||   ||   |_____a+ba+b-ca+b*ca*b+c(a+b)*c*/public static void main(String[] args) {System.out.println(infixToSuffix("a+b"));System.out.println(infixToSuffix("a+b-c"));System.out.println(infixToSuffix("a+b*c"));System.out.println(infixToSuffix("a*b-c"));System.out.println(infixToSuffix("(a+b)*c"));System.out.println(infixToSuffix("a+b*c+(d*e+f)*g"));}static String infixToSuffix(String exp) {LinkedList<Character> stack = new LinkedList<>();StringBuilder sb = new StringBuilder(exp.length());for (int i = 0; i < exp.length(); i++) {char c = exp.charAt(i);switch (c) {case '+', '-', '*', '/' -> {if (stack.isEmpty()) {stack.push(c);} else {if (priority(c) > priority(stack.peek())) {stack.push(c);} else {while (!stack.isEmpty()&& priority(stack.peek()) >= priority(c)) {sb.append(stack.pop());}stack.push(c);}}}case '(' -> {stack.push(c);}case ')' -> {while (!stack.isEmpty() && stack.peek() != '(') {sb.append(stack.pop());}stack.pop();}default -> {sb.append(c);}}}while (!stack.isEmpty()) {sb.append(stack.pop());}return sb.toString();}static int priority(char c) {return switch (c) {case '(' -> 0;case '*', '/' -> 2;case '+', '-' -> 1;default -> throw new IllegalArgumentException("不合法字符:" + c);};}
}

4.双栈模拟队列-力扣 232 题

给力扣题目用的自实现栈,可以定义为静态内部类

class ArrayStack<E> {private E[] array;private int top; // 栈顶指针@SuppressWarnings("all")public ArrayStack(int capacity) {this.array = (E[]) new Object[capacity];}public boolean push(E value) {if (isFull()) {return false;}array[top++] = value;return true;}public E pop() {if (isEmpty()) {return null;}return array[--top];}public E peek() {if (isEmpty()) {return null;}return array[top - 1];}public boolean isEmpty() {return top == 0;}public boolean isFull() {return top == array.length;}
}

参考解答,注意:题目已说明

  • 调用 push、pop 等方法的次数最多 100
public class E04Leetcode232 {/*队列头      队列尾s1       s2顶   底   底   顶abcpush(a)push(b)push(c)pop()*/ArrayStack<Integer> s1 = new ArrayStack<>(100);ArrayStack<Integer> s2 = new ArrayStack<>(100);public void push(int x) {s2.push(x);}public int pop() {if (s1.isEmpty()) {while (!s2.isEmpty()) {s1.push(s2.pop());}}return s1.pop();}public int peek() {if (s1.isEmpty()) {while (!s2.isEmpty()) {s1.push(s2.pop());}}return s1.peek();}public boolean empty() {return s1.isEmpty() && s2.isEmpty();}}

5.单队列模拟栈-力扣 225 题

给力扣题目用的自实现队列,可以定义为静态内部类

public class ArrayQueue3<E> {private final E[] array;int head = 0;int tail = 0;@SuppressWarnings("all")public ArrayQueue3(int c) {c -= 1;c |= c >> 1;c |= c >> 2;c |= c >> 4;c |= c >> 8;c |= c >> 16;c += 1;array = (E[]) new Object[c];}public boolean offer(E value) {if (isFull()) {return false;}array[tail & (array.length - 1)] = value;tail++;return true;}public E poll() {if (isEmpty()) {return null;}E value = array[head & (array.length - 1)];head++;return value;}public E peek() {if (isEmpty()) {return null;}return array[head & (array.length - 1)];}public boolean isEmpty() {return head == tail;}public boolean isFull() {return tail - head == array.length;}
}

参考解答,注意:题目已说明

  • 调用 push、pop 等方法的次数最多 100
  • 每次调用 pop 和 top 都能保证栈不为空
public class E05Leetcode225 {/*队列头     队列尾cba顶           底queue.offer(a)queue.offer(b)queue.offer(c)*/ArrayQueue3<Integer> queue = new ArrayQueue3<>(100);int size = 0;public void push(int x) {queue.offer(x);for (int i = 0; i < size; i++) {queue.offer(queue.poll());}size++;}public int pop() {size--;return queue.poll();}public int top() {return queue.peek();}public boolean empty() {return queue.isEmpty();}
}

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

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

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

相关文章

WEBGL(5):绘制线

1 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, …

springboot web开发登录拦截器

在SpringBoot中我们可以使用HandlerInterceptorAdapter这个适配器来实现自己的拦截器。这样就可以拦截所有的请求并做相应的处理。 应用场景 日志记录&#xff0c;可以记录请求信息的日志&#xff0c;以便进行信息监控、信息统计等。权限检查&#xff1a;如登陆检测&#xff…

HTML5

写在前面 一、简单认识HTML 1.1 什么是网页【2023/08/31】 网站是指因特网上根据一定的规则&#xff0c;使用HTML等制作的用于展示特定内容相关的网页集合。 网页是网站中的一“页”&#xff0c;通常是HTML格式的文件&#xff0c;它要通过浏览器来阅读。 网页是构成网站的…

pycharm 下jupyter noteobook显示黑白图片不正常

背景现象&#xff1a; 1、显示一张黑白图片&#xff0c;颜色反过来了。 from IPython.display import display source Image.open(examples/images/forest_pruned.bmp) display(source) 2、原因&#xff1a; 是pycharm会在深色皮肤下默认反转jupyter notebook输出图片的颜…

在线音乐播放器测试报告

文章目录 一、项目背景二、项目功能三、测试目的四、测试环境五、测试计划5.1 功能测试5.2 自动化测试 六、测试结果 一、项目背景 今天&#xff0c;市面上的音乐播放器种类繁多同时功能强大。一个单纯的音乐播放器可能不再单纯只是音乐播放的功能&#xff0c;而是更多地集短视…

Vue框架--Vue中的事件

1.事件处理 事件的基本使用: (1).使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名; (2).事件的回调需要配置在methods对象中,最终会在vm上; (3).methods中配置的函数,不要用箭头函数!否则this就不是vm了; (4).methods中配置的函数,都是被Vue所管理的函数,this的…

9.Redis-zset

zset zset 有序集合 -> 升序常用命令zaddzcardzcountzrangezrevrange -> reverse 逆序zrangebyscorezpopmaxzpopminbzpopmax / bzpopminzrankzrevrankzscorezremzremrangebyrankzremrangebyscorezincrby集合间操作zinter -> 交集zunion -> 并集zdiff -> 差集zin…

访问 GitHub 方法

访问 GitHub 方法 方法一&#xff1a;最常见的就是 fq&#xff0c;但这个是违法的行为&#xff0c;自己私下搞可以&#xff0c;不能教你们。 方法二&#xff1a;利用加速器&#xff0c;这是正规合法操作。这里推荐一个免费的加速器&#xff0c;下载安装 Watt Toolkit加速器,原名…

count(1)与count(*)的区别、ROUND函数

部分问题 1. count(1)与count(*)的区别2. ROUND函数3. SQL19 分组过滤练习题4. Mysql bigdecimal 与 float的区别5. 隐式内连接与显示内连接 &#xff08;INNER可省略&#xff09; 1. count(1)与count(*)的区别 COUNT(*)和COUNT(1)有什么区别&#xff1f; count(*)包括了所有…

3DS Max中绘制圆锥箭头

3DS Max中绘制圆锥箭头 绘制结果绘制过程步骤一&#xff1a;绘制立体圆锥方法1方法2 步骤二&#xff1a;圆锥体调参&#xff08;模型尺寸设置&#xff09;1圆锥体参数说明2圆锥体参数调整 步骤三&#xff1a;绘制圆柱体步骤四&#xff1a;圆柱体调参步骤五&#xff1a;圆锥与圆…

JavaExcel:自动生成数据表并插入数据

故事背景 出于好奇&#xff0c;当下扫描excel读取数据进数据库 or 导出数据库数据组成excel的功能层出不穷&#xff0c;代码也是前篇一律&#xff0c;poi或者easy excel两种SDK的二次利用带来了各种封装方法。 那么为何不能直接扫描excel后根据列的属性名与行数据的属性建立S…

yolov5的pytorch配置

1. conda create -n rdd38 python3.82、pip install torch1.8.0 torchvision0.9.0 torchaudio0.8.0 -f https://download.pytorch.org/whl/cu113/torch_stable.html -i https://pypi.tuna.tsinghua.edu.cn/simple 3、conda install cudatoolkit10.2

使用Docker配置深度学习的运行环境

文章目录 推荐实验环境前言docker安装docker操作docker配置常见方法&#xff08;安装包、联网、程序管理器&#xff09;安装驱动的前提要求传统方法安装驱动程序程序管理器安装联网安装deb包安装 安装完成后的设置非传统方法安装-通过容器安装驱动的前提要求安装NVIDIA-Contain…

基于Django的博客管理系统

1、克隆仓库https://gitee.com/lylinux/DjangoBlog.git 若失效&#xff1a;https://gitee.com/usutdzxy/DjangoBlog.git 2、环境安装 pip install -Ur requirements.txt3、修改djangoblog/setting.py 修改数据库配置&#xff0c;其他的步骤就按照官方文档。 DATABASES {def…

在 Amazon 搭建无代码可视化的数据分析和建模平台

现代企业常常会有利用数据分析和机器学习帮助解决业务痛点的需求。如制造业中&#xff0c;利用设备采集上来的数据做预测性维护&#xff0c;质量控制&#xff1b;在零售业中&#xff0c;利用客户端端采集的数据做渠道转化率分析&#xff0c;个性化推荐等。 亚马逊云科技开发者…

低代码赋能| 绿色智慧矿山解决方案

在世界能源日趋紧张的背景下&#xff0c;能源产业的数字化升级是大势所趋。矿山行业作为国家能源安全的“压舱石”&#xff0c;也必须进行产业升级。一直以来&#xff0c;国家都在大力推动智慧矿山建设。通过大数据、GIS、物联网、云计算、人工智能等新兴技术&#xff0c;实现矿…

R语言图形的组合( par(),layout(),par(fig()) )

引入d.class进行画图 > d.class<-read.csv("D://class.csv",header T) > attach(d.class) > opar<-par(no.readonly TRUE)非常简单的数据&#xff0c;需要可自取 链接&#xff1a;https://pan.baidu.com/s/1zNx5z9JsaaRqFueRgGY3mQ 提取码&#x…

微信小程序新版隐私协议弹窗实现最新版

1. 微信小程序又双叒叕更新了 2023.08.22更新&#xff1a; 以下指南中涉及的 getPrivacySetting、onNeedPrivacyAuthorization、requirePrivacyAuthorize 等接口目前可以正常接入调试。调试说明&#xff1a; 在 2023年9月15号之前&#xff0c;在 app.json 中配置 __usePriva…

Vite打包性能优化及填坑

最近在使用 Vite4.0 构建一个中型前端项目的过程中&#xff0c;遇到了一些坑&#xff0c;也做了一些项目在构建生产环境时的优化&#xff0c;在这里做一个记录&#xff0c;以便后期查阅。(完整配置在后面) 上面是dist文件夹的截图&#xff0c;里面的内容已经有30mb了&#xff…

Revit SDK:SpatialFieldGradient 在面上显示渐变颜色(AVF)分析显示样式

前言 这个例子使用Revit显示样式功能将面显示成不同的颜色。分析显示样式参考官方文档。 内容 效果&#xff1a; 核心逻辑&#xff1a; 得到一个 SpatialFieldManager拾取一系列的面&#xff1a;uiDoc.Selection.PickObjects(ObjectType.Face)计算面上的 UV 值&#xff0c;…