【数据结构】 栈(Stack)的应用场景

这篇具有很好参考价值的文章主要介绍了【数据结构】 栈(Stack)的应用场景。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🌏前言

栈(Stack)又名堆栈,作为一个== 先进后出== 的数据结构。

它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景

🍀改变元素的序列

🚩场景一

  1. 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是(C
    A: 1,4,3,2 B: 2,3,4,1 C: 3,1,4,2 D: 3,4,2,1

📌解析:

  • A选项进出入栈顺序:
  • push(1)->push(2)->push(3)->push(4)->pop(4)->pop(3)->pop(2);
  • B选型的出入栈顺序:
  • push(1)->push(2)->pop(2)->push(3)->pop(3)->push(4)->pop(4)->pop(1);
  • C选项出入栈顺序:
  • push(1)->push(2)->push(3)->pop(3)------->?pop(1)
  • 这时候我们的我们的栈内元素为:
  • 【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景
  • 所以C选项错误
  • D选项出入栈顺序:
  • pusn(1)->push(2)->push(3)->pop(3)->push(4)->pop(4)->pop(2)->pop(1);

🚩场景二

  1. 一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的顺序是( B )。
    A: 12345ABCDE B: EDCBA54321
    C: ABCDE12345 D: 54321EDCBA

📌解析:

依次入栈后,栈内元素为:
【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景
所以答案为B;

🎍将递归转化为循环

比如:逆序打印链表

在我们没有学习栈以前,我们可能会使用递归的方法进行打印,如下所示:

    // 递归方式
    void printList(Node head){
        if(null != head){
            printList1(head.next);
            System.out.print(head.val + " ");
        }
    }
    // 循环方式
    void printList1(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 + " ");
        }

🌳括号匹配

🚩题目描述:

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。
class Solution {
    public boolean isValid(String s) {
        
    }
}

🚩示例:

【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景

🚩思路解析:

我们利用栈的方法进行解决:

  • 如果是左括号,就让他进栈
  • 如果是右括号,就让它与栈顶元素进行比较
  • 如果栈顶元素与该右括号构成一对,则让栈顶元素出栈
  • 若不是一对,则返回false;

特殊情况考虑:

  • 右括号进来时栈为空,此时直接返回false就好
  • 左括号太多,遍历完后,栈内还有元素,这时候需要进行为空的判断
  • 若为空,返回true;反之则为false;

🚩代码实现:

class Solution {
    public boolean isValid(String s) {
        Stack<Character> characterStack = new Stack<>();
        for(int i = 0;i < s.length(); i++) {
            char ch1 = s.charAt(i);
            if(ch1 == '('||ch1 == '{' || ch1 == '[') {
                characterStack.push(ch1);
            } else {
                if(characterStack.empty()) {
                    return false;
                }
                char ch2 = characterStack.peek();
                if(ch2 == '('&&ch1 == ')' ||ch2 == '{'&&ch1 == '}' ||ch2 == '['&&ch1 == ']') {
                    characterStack.pop();
                } else {
                    return false;
                }
            }
        }
       if(characterStack.empty()) {
            return true;
        }
        return false;
    }
}

🎄逆波兰表达式求值

🐱‍👤拓展逆波兰式

🐱‍👓什么叫做逆波兰表达式

逻辑提问式类似于算术表达式,对于检索而言,这种表达式并不是最优和最简洁的形式,需要进行必要的转换。

1929年波兰的逻辑学家卢卡西维兹(Jan Lucasiewicz)提出了将运算符放在运算项后面的逻辑表达式,又称“逆波兰表达式”。

采用这种表达式组织逻辑提问式非常方便检索运算,是日本的福岛先生最早将逆波兰表达式应用于情报检索的,故又称为“福岛方法”。 [2]

逆波兰表达式又叫做后缀表达式,是一种没有括号,并严格遵循“从左到右”运算的后缀式表达方法,如下表所示:
【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景

🐱‍🐉逆波兰表达式算法步骤

  1. 首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。

  2. 读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。

  3. 从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。

  4. 如果不是数字,该字符则是运算符,此时需比较优先关系。具体做法是:将该字符与运算符栈顶的运算符的优先关系相比较。如果该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。若不是的话,则将栈顶的运算符从栈中弹出,直到栈项运算符的优先级低于当前运算符,将该字符入栈。

  5. 重复步骤1~2,直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。

🚩题目描述

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

🚨注意:

  • 有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。
  • 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
  • 两个整数之间的除法总是 向零截断 。
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。
class Solution {
    public int evalRPN(String[] tokens) {

    }
}

🚩示例:

【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景

🚩解法思路

如果当前字符为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

🚨注意:先出来的数为左操作数,后出来的数为右操作数

代码实现如下:

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

🌴出栈入栈次序匹配

🚩题目描述:

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列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 的所有数字均不相同

🚩示例

【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景

🚩解法思路:

我们就可以用一个栈来模拟。对于入栈序列,只要栈为空,序列肯定要依次入栈。那什么时候出来呢?自然是遇到一个元素等于当前的出栈序列的元素,那我们就放弃入栈,让它先出来。

具体做法:

  • 准备一个辅助栈,两个下标分别访问两个序列。
  • 辅助栈为空或者栈顶不等于出栈数组当前元素,就持续将入栈数组加入栈中。
  • 栈顶等于出栈数组当前元素就出栈。
  • 当入栈数组访问完,出栈数组无法依次弹出,就是不匹配的,否则两个序列都访问完就是匹配的。
    【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景

🚩代码实现:

import java.util.Stack;
public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        int n = pushA.length;
        //辅助栈
        Stack<Integer> s = new Stack<>();
        //遍历入栈的下标
        int j = 0;
        //遍历出栈的数组
        for(int i = 0; i < n; i++){
            //入栈:栈为空或者栈顶不等于出栈数组
            while(j < n && (s.isEmpty() || s.peek() != popA[i])){
                s.push(pushA[j]);
                j++;
            }
            //栈顶等于出栈数组
            if(s.peek() == popA[i])
                s.pop();
            //不匹配序列
            else
                return false;
        }
        return true;
    }
}

🌲最小栈

🚩题目描述:

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。
class MinStack {

    public MinStack() {

    }
    
    public void push(int val) {

    }
    
    public void pop() {

    }
    
    public int top() {

    }
    
    public int getMin() {

    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(val);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

🚩示例:

【数据结构】 栈(Stack)的应用场景,数据结构,数据结构,java,栈,应用场景

🚩思路解析:

我们创建两个栈

  • 一个用来存放我们的全部数据->stack
  • 一个用来存放最小栈->minStack
	private Stack<Integer> stack ;
    private Stack<Integer> minStack ;
    public MinStack() {
        stack = new Stack<>();
        minStack = new Stack<>();
    }

📌将元素val推入堆栈

做法如下:

  • stack无差别推入
  • 对于minStack进行判断,若为空,直接压入
  • 若不为空,则需要与栈顶元素进行比较
  • 若小于等于,则压入

代码实现如下:

    public void push(int val) {
        stack.push(val);
        if(minStack.empty()) {
            minStack.push(val);
        }else {
            if(val <= minStack.peek()) {
                minStack.push(val);
            }
        }
    }

📌删除堆栈顶部的元素

做法如下:

  • 对stack进行判断判断,若不为空。怎进行删除
  • 同样我们的minStack也需要进行判断,判断条件为:若栈顶元素等于stack所删除元素
  • 则minStack栈顶元素也要删除,目的时维护最小栈

代码实现如下:

    public void pop() {
        if(!stack.empty()) {
            Integer val = stack.pop();
            //维护最小栈
            if (val.equals(minStack.peek())) {
                minStack.pop();
            }
        }
    }

📌获取堆栈顶部的元素

  • 做一个是否为空的判断

  • 若不为直接返回栈顶元素就好

  • 若为空返回-1

代码实现如下:

    // peek
    public int top() {
        if(!stack.empty()) {
            return stack.peek();
        }
        return -1;
    }

📌获取堆栈中的最小元素

直接返回minStack栈顶元素就好

    public int getMin() {
        return minStack.peek();
    }

🚩完整代码:

class MinStack {

    private Stack<Integer> stack ;
    private 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 {
            if(val <= minStack.peek()) {
                minStack.push(val);
            }
        }
    }
    
    public void pop() {
        if(!stack.empty()) {
            Integer val = stack.pop();
            //维护最小栈
            if (val.equals(minStack.peek())) {
                minStack.pop();
            }
        }
    }
    // peek
    public int top() {
        if(!stack.empty()) {
            return stack.peek();
        }
        return -1;
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(val);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

⭕总结

关于《【数据结构】 栈(Stack)的应用场景》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!文章来源地址https://www.toymoban.com/news/detail-674652.html

到了这里,关于【数据结构】 栈(Stack)的应用场景的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构【栈】有哪些应用场景?

    ✨Blog:🥰不会敲代码的小张:)🥰 🉑推荐专栏: C语言 🤪、 Cpp 😶‍🌫️、 数据结构初阶 💀 💽座右铭:“ 記住,每一天都是一個新的開始😁😁😁 ” 💀本章内容: 《栈》的介绍✨ 本章会介绍 栈的特性 以及栈的初始化、销毁、插入、删除、取栈顶元素等… 那么栈的

    2024年02月08日
    浏览(51)
  • Redis数据结构应用场景及原理分析

    目录 一、Redis介绍 二、应用场景  2.1 String应用场景  2.2 Hash应用场景   2.3 List应用场景 2.4 Set应用场景  2.5 Zset应用场景  单线程 多路复用 底层数据结构:全局哈希表(key-value) 单值缓存 set key value get key  对象缓存 set user:1 userJson(Json格式数据) 分布式锁 set product:1 true

    2024年02月10日
    浏览(38)
  • Redis常用的数据结构及实际应用场景

    本文介绍了Redis中常用的数据结构,包括字符串、列表、集合、哈希表、有序集合和Bitmap,并结合实际案例详细说明了它们在各种场景下的使用。 Redis是一种基于内存的高性能键值存储系统,拥有多种数据结构,每种数据结构都具有独特的特点和适用场景。了解这些数据结构

    2024年02月08日
    浏览(53)
  • 深入理解数据结构:队列的实现及其应用场景

    队列(Queue)是一种具有先进先出(FIFO)特性的数据结构。在队列中,数据的插入和删除操作分别在队列的两端进行。插入操作在队列的尾部进行,而删除操作则在队列的头部进行。这种特性使得队列在很多实际应用中非常有用,比如任务调度、缓冲区管理等。 线性表是一种

    2024年04月28日
    浏览(53)
  • Redis的8种数据结构和应用场景介绍,面试题答案

    面试原题 :你用过Redis哪些数据结构?(网易一面 · 2023) (面试题来自牛客网) 参考答案 后面有 详细答案解析,帮助更快记忆~ 参考答案共652字符,阅读约需1分8秒;全文共8694字符,阅读约需7分14秒 Redis是一种流行的内存数据库,支持多种数据结构,用于不同的用途。下面

    2024年02月11日
    浏览(44)
  • 数据结构的应用场景:如社交网络、路由算法、图论、网络协议等

    作者:禅与计算机程序设计艺术 数据结构(Data Structure)是计算机科学中存储、组织、管理数据的方式,主要用于解决信息检索、处理和运算时的效率及空间占用问题。它是指数据元素(elements)之间的关系、顺序和逻辑结构,以及相互作用的算法。数据结构通常采用抽象数据类

    2024年02月14日
    浏览(47)
  • 本文通过实例介绍了Redis的基础知识、数据类型、数据结构以及典型应用场景 值得一看!

    作者:禅与计算机程序设计艺术 2017年,Redis是基于MIT许可发布的一个开源的高性能键值数据库,其开发语言为C语言。它提供了多种数据类型(strings、hashes、lists、sets、sorted sets等),分布式支持(可横向扩展),内存存储,持久化功能,事务处理功能等。作为一种高性能的

    2024年02月06日
    浏览(71)
  • 数据结构---栈(Stack)

    栈是一种 线性 数据结构 栈是\\\" 后进先出 (LIFO---Last In First Out)\\\"的数据结构(盘子的叠放:当服务员将新的盘子放在餐桌上时,他们通常会将盘子放在已有的盘子堆的顶部。当顾客用完盘子后,服务员会从堆顶取走盘子。这个过程就类似于栈的入栈和出栈操作。) 规定只能从 栈顶

    2024年01月21日
    浏览(41)
  • 数据结构——栈(Stack)

    目录 1.栈的介绍 2.栈工程 2.1 栈的定义 2.1.1 单链表实现栈 2.1.2 数组实现栈 2.1.2.1 静态数组栈 2.1.2.2 动态数组栈 2.2 栈的函数接口 2.2.1 栈的初始化 2.2.2 栈的数据插入(入栈) 2.2.3 栈的数据删除(出栈) 2.2.4 判断栈是否为空 2.2.5 取栈顶数据 2.2.6 栈数据统计 2.2.7 栈销毁 3. 栈总

    2024年01月21日
    浏览(43)
  • 【数据结构】栈(Stack)实现详解

    🚩 纸上得来终觉浅, 绝知此事要躬行。 🌟主页:June-Frost 🚀专栏:数据结构 🔥该文章主要了解实现栈的相关操作。  栈是一种特殊的线性表,其只允许在 固定的一端 进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底 。栈中的数据元

    2024年02月08日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包