2023-09-22  阅读(3)
原文作者:李林超 原文地址: https://www.lilinchao.com/archives/495.html

一、栈的一个实际需求

请输入一个表达式

计算式:[ 7*2*2-5+1-5+3-3 ] 点击计算 【如下图】

202309222128553631.png

请问: 计算机底层是如何运算得到结果的? 注意不是简单的把算式列出运算,因为我们看这个算式 7 * 2 * 2 - 5, 但是计算机怎么理解这个算式的 (对计算机而言,它接收到的就是一个 字符串 ),我们讨论的是这个问题**。-> **栈

二、栈的介绍

(1)栈的英文为(stack) > > (2)栈是一个先入后出(FILO-First In Last Out)的有序列表。 > > (3)栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为 变化的一端,称为栈顶(Top) ,另一端为 固定的一端称为栈低 (Bottom). > > (4)根据栈的定义可知,最先放入栈中的元素在栈低,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除

图解方式说明出栈(pop)和入栈(push)的概念

202309222128561192.png

三、栈的应用场景

  1. 1.子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。
  2. 2.处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。
  3. 3.表达式的转换【中缀表达式和后缀表达式】与求值
  4. 4.二叉树的遍历。
  5. 5.图形的深度优先(depth-first)搜索法。

四、栈的快速入门

1)用 数组模拟栈 的使用,由于栈是一种有序列表,当然可以使用数组的结构来储存栈的数据内容,下面我们就用数组模拟栈的 出栈入栈 等操作。

2)实现思路分析,并画出示意图

202309222128571553.png

实现栈的思路分析

  1. 1.使用数组来模拟栈 > 2. 2.定义一个top来表示栈顶,初始化为-1. > 3. 3.入栈的操作,当有数据加入到栈时,top++;stack[top]=data; > 4. 4.出栈的操作,int value=stack[top];top--,return value

代码

    package dataStructure;
    
    import java.util.Scanner;
    
    public class ArrayStackDemo {
        public static void main(String[] args) {
    
            ArrayStack stack = new ArrayStack(4);
            String key="";
            boolean loop = true;//控制是否退出菜单
            Scanner scanner = new Scanner(System.in);
    
            while(loop){
                System.out.println("show:表示显示栈");
                System.out.println("exit:退出程序");
                System.out.println("push:表示添加数据到栈(入栈)");
                System.out.println("pop:表示从栈取出数据(出栈)");
                System.out.println("请输入你的选择");
                key=scanner.next();
                switch (key){
                    case "show":
                        stack.list();
                        break;
                    case "push":
                        System.out.println("请输出一个数");
                        int value=scanner.nextInt();
                        stack.push(value);
                        break;
                    case "pop":
                        try{
                            int res =stack.pop();
                            System.out.printf("出栈的数据是%d\n",res);
                        }catch (Exception e){
                            System.out.println(e.getMessage());
                        }
                        break;
                    case "exit":
                        scanner.close();
                        loop = false;
                        break;
                    default:
                        break;
                }
            }
            System.out.println("程序退出");
        }
    }
    
    //定义一个ArrayStack表示栈
    class ArrayStack{
        private int maxSize;//栈的大小
        private int[] stack;//数组,数组模拟栈,数据就放在该数组
        private int top=-1;//top表示栈顶,初始化为-1
    
        //构造器
        public ArrayStack(int maxSize){
            this.maxSize=maxSize;
            stack=new int[this.maxSize];
        }
    
        //栈满
        public boolean isFull(){
            return top==maxSize-1;
        }
    
        //栈空
        public boolean isEmpty(){
            return top == -1;
        }
    
        //入栈push
        public void push(int value){
            //先判断栈是否满
            if(isFull()){
                System.out.println("栈满");
                return;
            }
            top++;
            stack[top]=value;
        }
        //出栈 pop 将栈顶的数据返回
        public int pop(){
            //先判断是否为空
            if(isEmpty()){
                //抛出异常
                throw new RuntimeException("栈空,没有数据");
            }
            int value=stack[top];
            top--;
            return value;
        }
        //显示栈的情况[遍历栈],遍历时,需要从栈顶开始显示数据
        public void list(){
            if(isEmpty()){
                System.out.println("栈空,没有数据");
                return;
            }
            //需要从栈顶开始显示数据
            for(int i=top;i>=0;i--){
                System.out.printf("stack[%d]=%d\n",i,stack[i]);
            }
        }
    }

Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文