zoukankan      html  css  js  c++  java
  • 四、栈

    1、栈的介绍

     

     

    2、栈的应用场景

       1)子程序的调用:在跳往子程序前,会先将下一个指令的地址存储到堆栈中,知道子程序执行完成后再将地址取出,以回到原来的程序中。

       2)处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。

       3)表达式的转换【中缀表达式转成后缀表达式】与求职。

       4)二叉树的遍历。

       5)图形的深度优先(depth-first)搜索法。

    3、栈的快速入门

        1)用数组模拟栈的使用,由于栈是一种有序列表,当然可以用数组的数据结构来存储栈的数据内容。

       2)示意图:

       3)代码实现:

    package com.stack;
    
    import java.util.Scanner;
    
    public class ArrayStackDemo {
        public static void main(String[] args) {
            ArrayStack arrayStack = new ArrayStack(10);
            String key = "";
            Scanner sc = new Scanner(System.in);
            boolean loop = true;
    
            while (loop) {
                System.out.println("push:添加数据入栈");
                System.out.println("pop:添加数据出栈");
                System.out.println("list:遍历栈数据");
                System.out.println("exit:退出");
                key = sc.next();
                switch (key) {
                    case "push":
                        System.out.println("请输入一个数据");
                        int value = sc.nextInt();
                        arrayStack.push(value);
                        break;
                    case "pop":
                        int reval = arrayStack.pop();
                        System.out.println("出栈的数据为:" + reval);
                        break;
                    case "list":
                        arrayStack.list();
                        break;
                    case "exit":
                        sc.close();
                        loop = false;
                        break;
                    default:
                        break;
                }
            }
            System.out.println("程序退出~~~~~~~~");
        }
    }
    
    //定义一个ArrayStack栈
    class ArrayStack {
        private int maxSize;
        private int[] stack;
        private int top = -1;
    
        public ArrayStack(int maxSize) {
            this.maxSize = maxSize;
            stack = new int[maxSize];
        }
    
        //栈满
        public boolean isFull() {
            return top == maxSize - 1;
        }
    
        //栈空
        public boolean isEmpty() {
            return top == -1;
        }
    
        //入栈
        public void push(int data) {
            if (isFull()) {
                System.out.println("栈满了,不能加入数据");
                return;
            }
            top++;
            stack[top] = data;
        }
    
        //出栈
        public int pop() {
            if (isEmpty()) {
                System.out.println("栈空的,不能取数据");
                return 0;
            }
            int redata = stack[top];
            top--;
            return redata;
        }
    
        //遍历栈
        public void list() {
            if (isEmpty()) {
                System.out.println("栈空的,不能取数据");
                return;
            }
            for (int i = 0; i < stack.length; i++) {
                System.out.printf("stack[%d]=%d
    ", i, stack[i]);
            }
        }
    
    }

     4、使用栈做一个逆波兰计算器(后缀表达式)

     代码实现:

    package com.stack;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Stack;
    
    public class PolandNotation {
        public static void main(String[] args) {
            String exp = "4 5 * 8 - 60 + 8 2 / +";
            List<String> list = getListString(exp);
            int res = calculate(list);
            System.out.println("计算结果为:"+res);
    
        }
    
        //后缀表达式的计算
        public static int calculate(List<String> ls){
            Stack<String> stack = new Stack<>();
            for(String item:ls){
                if(item.matches("\d+")){//匹配的是多位数
                    stack.push(item);
                }else{
                    //pop出两个数,并计算,计算完成后再入栈
                    int num1 = Integer.parseInt(stack.pop());
                    int num2 = Integer.parseInt(stack.pop());
                    int result = 0;
                    if(item.equals("+")){
                        result = num2+num1;
                    }else if(item.equals("-")){
                        result  = num2-num1;
                    }else if(item.equals("*")){
                        result = num2*num1;
                    }else if(item.equals("/")){
                        result = num2/num1;
                    }else{
                        System.out.println("运算符有误");
                    }
                    stack.push(""+result);
                }
            }
            return Integer.parseInt(stack.pop());
        }
    
        //将一个后缀表达式,放入到ArrayList中
        public static List<String> getListString(String expression){
            String[] split = expression.split(" ");
            List<String> list = new ArrayList<>();
            for(String s:split){
                list.add(s);
            }
            return list;
        }
    }

    5、中缀表达式转换后缀表达式

       具体思路步骤如下:

       举例:

     

     代码实现:

    //将得到的中缀表达式对应的list转成对应的后缀表达式
        public static List<String> parseSuffixExpression(List<String> ls){
            Stack<String> s1= new Stack<>();//符号栈
            List<String> l1 = new ArrayList<>();//结果栈,存放中间结果
            for(String item:ls){
                if(item.matches("\d+")){
                    l1.add(item);
                }else if(item.equals("(")){
                    s1.add(item);
                }else if(item.equals(")")){
                    //如果是右括号,则依次弹出是s1栈顶的运算符,并压入l1,直到遇到左括号,并消除左括号
                    while (!s1.peek().equals("(")){
                        l1.add(s1.pop());
                    }
                    s1.pop();//弹出左小括号
                }else {//比较运算符的优先级
                    //当item的优先级小于等于s1栈顶运算符,将s1栈顶的运算符弹出并加入到l1
                    //再比较
                    while (s1.size()>0 && getValue(s1.peek()) >= getValue(item)){
                        l1.add(s1.pop());
                    }
                    //如果是大于当前s1栈顶的优先级,则直接压入
                    s1.push(item);
                }
            }
            while(s1.size()!=0){
                l1.add(s1.pop());
            }
            return l1;
        }
    
        //比较运算符的优先级
        public static int getValue(String operation){
            int result = 0;
            switch (operation){
                case "+":
                    result  = 1;
                    break;
                case "-":
                    result = 1;
                    break;
                case "*":
                    result = 2;
                    break;
                case "/":
                    result = 2;
                    break;
                default:
                    System.out.println("不存在该运算符");
                    break;
            }
            return result;
        }
  • 相关阅读:
    Springboot 之 自定义配置文件及读取配置文件
    SQLSERVER系统视图 sql server系统表详细说明
    MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义
    使用Ecplise git commit时出现"There are no stages files"
    maven添加sqlserver的jdbc驱动包
    java将XML文档转换成json格式数据
    java将XML文档转换成json格式数据
    cannot be resolved. It is indirectly referenced from required .class files
    org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value '2012-12-12 12:01:01': not a valid representation (error: Can not parse date "2012-12-
    @Autowired注解和静态方法 NoClassDefFoundError could not initialize class 静态类
  • 原文地址:https://www.cnblogs.com/zsy-code/p/13511901.html
Copyright © 2011-2022 走看看