2023-09-22
原文作者:李林超 原文地址: 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]);
            }
        }
    }
阅读全文