一.定义

栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为先进后出表。栈可以用来在函数调用的时候存储断点,做递归时要用到栈!

二.基于数组实现栈

1.思路

 

 

 1.定义数组实现栈

public 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 value){
        if (isFull()){
            System.out.println("栈满");
            return;
        }
        top++;
        stack[top]=value;
    }

    /*出栈*/
    public  int pop(){
        if (isEmpty()){
            throw new RuntimeException("空栈");
        }
        int res = stack[top];
         top--;
        return res;
    }

    /*遍历栈*/
    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]);
        }
    }

}

2.进行测试

public class ArrayStackDemo {
    public static void main(String[] args) {
        ArrayStack arrayStack = new ArrayStack(4);
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;
        while (loop){
            System.out.println("s(show):显示栈");
            System.out.println("e(exit):退出程序");
            System.out.println("a(push):添加数据");
            System.out.println("g(pop):取数据");
            key = scanner.next().charAt(0);//接收数据
            switch (key){
                case 's':
                  arrayStack.list();
                    break;
                case 'a':
                    System.out.println("请输入数据");
                    int value = scanner.nextInt();
                     arrayStack.push(value);
                    break;
                case 'g':
                    try {
                        int res = arrayStack.pop();
                        System.out.printf("取出的数据:%d\n",res);
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出");
    }
}

三.利用栈结构实现计算器

1.思路

 

 1.利用数组定义一个栈

public class ArrayStack2 {
    private int maxSize;//栈的大小
    private int[] stack;//数组模拟栈
    private int top=-1;//栈顶

    /*构造器*/
    public ArrayStack2(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 value){
        if (isFull()){
            System.out.println("栈满");
            return;
        }
        top++;
        stack[top]=value;
    }

    /*出栈*/
    public  int pop(){
        if (isEmpty()){
            throw new RuntimeException("空栈");
        }
        int res = stack[top];
         top--;
        return res;
    }

    /*遍历栈*/
    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]);
        }
    }


    /*显示栈顶元素*/
    public  int peek(){
        return stack[top];
    }

    /*返回运算符的优先级,优先级越大数字就越大*/
   public  int priority(int oper){
       if (oper == '*'||oper=='/'){
           return 1;
       }else if (oper=='+'||oper=='-'){
           return 0;
       }else {
           return -1;
       }
   }

   /*判断是不是一个符号*/
    public  boolean isOper(char val){
        return val=='+'||val=='-'||val=='*'||val=='/';
    }
   /*计算方法*/
    public int cal(int num1, int num2,int val){
        int res = 0;
        switch (val){
            case'+':
               res=num1+num2;
               break;
            case'-':
                res=num2-num1;
                break;
            case'*':
                res=num1*num2;
                break;
            case'/':
                res=num2/num1;
                break;
            default:
                break;
        }
        return res;
    }

2.判断运算符的优先级

public class Operation {
    private static int ADD=1;
    private static int SUB=1;
    private static int MUL=2;
    private static int DIV=2;
    /*返回对应的优先级*/
    public  static int getValue(String operation){
        int res = 0;
        switch (operation){
            case "+":
                res = ADD;
                break;
            case "-":
                res = SUB;
                break;
            case "*":
                res = MUL;
                break;
            case "/":
                res = DIV;
                break;
            default:
              System.out.println("运算符有误");
                break;
        }
        return res;
    }

}

3.进行测试

public class Calculator {
    public static void main(String[] args) {
        String expression = "70+2*6-4";
        /*创建数栈和符号栈*/
        ArrayStack2 numStack = new ArrayStack2(10);
        ArrayStack2 operStack = new ArrayStack2(10);
        //定义相关变量
        String keepNum="";
        int index = 0;
        int num1= 0;
        int num2= 0;
        int oper= 0;
        int res=0;
        char ch=' ';//将每次扫描的char保存到ch;
        //开始扫描
        while (true){
            //依次得到字符
            ch = expression.substring(index,index+1).charAt(0);
            if (operStack.isOper(ch)){//如果是运算符
                       //判断栈空
                if (!operStack.isEmpty()){
                    //处理
                    /*如果入栈的操作符的优先级小于或者等于栈中的操作符
                    * 就后,将从数栈中pop出两个数,再从符号栈中pop出一个符号进行运算
                    * 然后,将结果入栈,
                    * 然后将当前的符号入栈*/
                    if (operStack.priority(ch)<=operStack.priority(operStack.peek())){
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operStack.pop();
                        res =numStack.cal(num1,num2,oper);
                        //将结果入栈
                        numStack.push(res);
                        //将当前的符号入栈
                        operStack.push(ch);
                    }else {
                        /*如果入栈的操作符的优先级大于栈中的操作符,直接入符号栈*/
                        operStack.push(ch);
                    }
                }else {
                    //为空直接入符号栈
                    operStack.push(ch);
                }
            }else {//如果是数直接入符号栈
                 //numStack.push(ch-48);
                /*处理多位数时*/
               keepNum+=ch;
               if (index==expression.length()-1){//如果是最后一位直接入数栈
                   numStack.push(Integer.parseInt(keepNum));
               }else {
               /*判断下一个字符是否是数字
               是:继续扫描
               否:入符号栈*/
                   if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
                       numStack.push(Integer.parseInt(keepNum));
                       keepNum = "";/*//清空*/
                   }
               }
            }

            /*让指针+1判断是否扫描到最后*/
            index++;
            if (index>=expression.length()){
                break;
            }

        }

        /*扫描完成后将数栈和符号栈中的pop对应的数和符号进行运算*/
        while (true){
            if (operStack.isEmpty()){//计算最后结果
                break;
            }
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            res =numStack.cal(num1,num2,oper);
            numStack.push(res);//入栈
        }
        int he = numStack.pop();
        System.out.printf("表达%s = %d",expression,he);


    }

}

 

posted @ 2020-04-21 21:52  苏先生139  阅读(162)  评论(0编辑  收藏  举报