编程语言
首页 > 编程语言> > 数据结构与算法之栈

数据结构与算法之栈

作者:互联网

1>栈的基本介绍

1.1、栈的实际需求

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

在这里插入图片描述

1.2、栈的基本性质

栈的英文为(stack)
栈是一个先入后出(FILO-First In Last Out)的有序列表
栈(stack)是限制线性表中元素的插入和删除只能在线性表的
同一端进行的一种特殊线性表。
允许插入和删除的一端,为变化的一端,称为栈顶(Top),
另一端为固定的一端, 称为栈底(Bottom)。
根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,
而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除
图解方式说明出栈(pop)和入栈(push)的概念

在这里插入图片描述

1.3、栈的应用场景

2>数组模拟栈

2.1、代码思路

2.2、代码实现

package com;

public class StackNode {
    public int maxsize;
    public int[] stack;
    public int top = -1;

    public StackNode(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;
        }
        stack[++top] = data;
    }
    public int pop()
    {
        if (isEmpty()){
            throw new RuntimeException("栈空,无法pop出元素");
        }
        return stack[top--];
    }
    public void list()
    {
        if (isEmpty())
            throw new RuntimeException("栈空,无法遍历元素");
        for (int i = top;i>=0;i--)
        {
            System.out.printf("stack[%d] = %d\n",i,stack[i]);
        }
    }
}
package com;

import java.util.Scanner;

public class Test03 {
    public static void main(String[] args) {
        StackNode stackNode = new StackNode(4);
        Scanner scanner = new Scanner(System.in);
        String key = "";
        boolean k = true;
        while (k) {
            System.out.println("show:表示显示栈");
            System.out.println("exit:退出程序");
            System.out.println("push:入栈");
            System.out.println("pop:出栈");
            key = scanner.next();
            switch (key) {
                case "show":
                    stackNode.list();
                    break;
                case "exit":
                    k = false;
                    break;
                case "push":
                    System.out.println("请输出一个数据");
                    int value = scanner.nextInt();
                    stackNode.push(value);
                    break;
                case "pop":
                    System.out.println("出栈数据为" + stackNode.pop());
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序已退出");
    }
}

2.3>课后作业

使用链表模拟栈

3>栈实现综合计算器(中缀表达式)

3.1、代码思路

2
3	  +
数栈	符号栈
6
2	  *
3	  +
数栈	符号栈
12	  -
3	  +
数栈	符号栈
2
12	  -
3	  +
数栈	符号栈
10
3	  +
数栈	符号栈
13
数栈	符号栈

在这里插入图片描述

3.2、代码实现

栈的定义:专为计算器而生的栈
对于乘除法特别说明:
由于栈先进后出的特点,
num1 是运算符后面的数(减数、除数),
num2 是运算符前的数(被减数、被除数),
特别需要注意减法与除法的顺序
res = num2 - num1;
res = num2 / num1;
package com;

public class CalStack {
    public int maxsize;
    public int[] stack;
    public int top = -1;

    public CalStack(int maxsize)
    {
        this.maxsize = maxsize;
        stack = new int[maxsize];
    }
    public boolean isEmpty()
    {
        return top == -1;
    }
    public boolean isFull()
    {
        return top == maxsize - 1;
    }
    public void push(int data)
    {
        if (isFull())
        {
            throw new RuntimeException("栈已满");
        }
        stack[++top] = data;
    }
    public int pop()
    {
        if (isEmpty())
            throw new RuntimeException("栈是空的");
        return stack[top--];
    }
    public int priority(int oper)
    {
        if (oper == '*' || oper == '/'){
            return 1;}
        else if (oper == '+' || oper == '-') {
            return 0;}
        else {
            return -1;
        }
    }
    public int cal(int num1,int num2,int oper)
    {
        int value =0;
        switch (oper)
        {
            case '+':
                value = num1 + num2;
                break;
            case '-':
                value = num2 - num1;
                break;
            case '*':
                value = num1 * num2;
                break;
            case '/':
                value = num2 / num1;
                break;
        }
        return value;
    }
    public boolean isOper(char c)
    {
        return c == '+'||c == '-'||c == '*'||c =='/';
    }
    public int peek()
    {
        if (isEmpty())
            throw new RuntimeException("栈为空,栈顶无元素");
        return stack[top];
    }
}
package com;

public class Test04 {
    public static void main(String[] args) {
        CalStack numStack = new CalStack(10);
        CalStack opeStack = new CalStack(10);
        char c = ' ';
        char d = ' ';
        int e = 0;
        String s = "";
        int num1 = 0;
        int num2 = 0;
        int index = 0;
        String expression = "70*2*2-5+1-5+3-4";
        int size = expression.length();
        while (true) {
            c = expression.charAt(index);
            if (index == size - 1) {
                int f = Integer.parseInt(String.valueOf(c));
                System.out.println(f);
                numStack.push(f);
                System.out.println(numStack.peek());
                break;
            }
            if (opeStack.isOper(c)) {
                if (opeStack.isEmpty())
                    opeStack.push(c);
                else {
                    if (opeStack.priority(c) > opeStack.priority(opeStack.peek())) {
                        opeStack.push(c);
                    } else {
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        e = opeStack.pop();
                        opeStack.push(c);
                        numStack.push(numStack.cal(num1, num2, e));
                        //System.out.println(numStack.cal(num1, num2, e));
                    }
                }
                //System.out.println(c);
                index++;
            } else {
                s += c;
                d = expression.charAt(index + 1);
                if (opeStack.isOper(d)) {
                    numStack.push(Integer.parseInt(s));
                    s = "";
                }
                //numStack.push(Integer.parseInt(s));
                index++;
            }
        }
        while (true)
        {
            if (opeStack.isEmpty())
            {
                System.out.printf("%s的结果是%d",expression,numStack.pop());
                break;
            }
            num1 = numStack.pop();
            //System.out.println("num1 = " +num1);
            num2 = numStack.pop();
            e = opeStack.pop();
            //System.out.println(numStack.cal(num1,num2,e));
            numStack.push(numStack.cal(num1,num2,e));
        }
    }
}

4>前缀 中缀 后缀表达式

4.1、前缀表达式(波兰表达式)

4.1.1、前缀表达式

4.1.2、前缀表达式的计算机求值

4.2、中缀表达式

4.3、后缀表达式

4.3.1、后缀表达式

正常的表达式逆波兰表达式
a+ba b +
a+(b-c)a b c - +
a+(b-c)*da b c – d * +
a+d*(b-c)a d b c - * +
a=1+3a 1 3 + =

4.3.2、后缀表达式的计算机求值

5>逆波兰计算器

5.1、计算器说明

5.2、代码思路

5.3、代码实现

public class Test05 {
    public static void main(String[] args) {
        String suffixExpression = "4 5 * 8 - 60 + 8 2 / +"; // 76
        String[] split = suffixExpression.split(" ");
        List<String> list = new ArrayList<>();
        for (String s : split) {
            list.add(s);
        }
        for (String s:list) {
            System.out.println(s);
        }
        System.out.printf("后缀表达式%s的结果为%d", suffixExpression, cal(list));
        //System.out.printf("后缀表达式%s的结果为%d",expression,cal(list));
    }
        public static int cal(List<String> list) {
        Stack<String> stack = new Stack<>();
        int num1 = 0;
        int num2 = 0;
        int result = 0;
        for (String s : list) {
            if (s.matches("\\d+")) {
                stack.push(s);
            } else {
                num1 = Integer.parseInt(stack.pop());
                num2 = Integer.parseInt(stack.pop());
                switch (s) {
                    case "+":
                        result = num1 + num2;
                        break;
                    case "-":
                        result = num2 - num1;
                        break;
                    case "*":
                        result = num1 * num2;
                        break;
                    case "/":
                        result = num2 / num1;
                        break;
                }
                stack.push(""+result);
            }
        }
        return Integer.parseInt(stack.pop());
    }
  }

6>中缀表达式转后缀表达式

6.1、代码思路

基于堆栈的算法

c++堆栈的应用:中缀表达式转化为后缀表达式

在这里插入图片描述
在这里插入图片描述

6.2、举例说明

在这里插入图片描述

6.3、代码实现

public class Test05 {
    public static void main(String[] args) {
        String expression = "1+((2+3)*4)-5";
        List<String> list = new ArrayList<>();
        list = change(expression);
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()!=false)
        {
            System.out.println(iterator.next());
        }
        System.out.printf("中缀表达式%s的结果为%d", expression, cal(list));
        
    public static List<String> change(String expression) {
        List<String> list = new ArrayList<>();
        Stack<Character> stack = new Stack<>();
        int size = expression.length();
        int index = 0;
        char c = ' ';
        char d = ' ';
        String s = "";
        while(true)
        {
            c = expression.charAt(index);
            if (index == size-1)
            {
                list.add(String.valueOf(c));
                while (stack.isEmpty()!=true)
                {
                    list.add(String.valueOf(stack.pop()));
                }
                break;
            }
            if (c<48||c>57)
            {
            if (stack.isEmpty() && c !=')')
            {
                stack.push(c);
            }
            else {
                if (c == '(') {
                    stack.push(c);
                } else if (c == ')') {
                    while (true) {
                        d = stack.pop();
                        if (d == '(') {
                            break;
                        }
                        list.add(String.valueOf(d));
                    }
                } else if (stack.peek() == '(') {
                    stack.push(c);
                } else if (priority(stack.peek()) >= priority(c)) {
                    while (true) {
                        if (stack.isEmpty() || priority(c) > priority(stack.peek()))
                            break;
                        list.add(String.valueOf(stack.pop()));
                    }
                    stack.push(c);
                }
            }
            index++;
            }
            else {
                s+=c;
                if (expression.charAt(index+1)<48||expression.charAt(index+1)>57)
                {
                    list.add(s);
                    s = "";
                }
                index++;
            }
        }
        return list;
    }

    public static int priority(char s)
    {
        if (s == '*'||s == '/')
        {
            return 1;
        }
        else if (s == '+'||s == '-')
        {
            return 0;
        }
        else {
            return -1;
        }
    }

    public static int cal(List<String> list) {
        Stack<String> stack = new Stack<>();
        int num1 = 0;
        int num2 = 0;
        int result = 0;
        for (String s : list) {
            if (s.matches("\\d+")) {
                stack.push(s);
            } else {
                num1 = Integer.parseInt(stack.pop());
                num2 = Integer.parseInt(stack.pop());
                switch (s) {
                    case "+":
                        result = num1 + num2;
                        break;
                    case "-":
                        result = num2 - num1;
                        break;
                    case "*":
                        result = num1 * num2;
                        break;
                    case "/":
                        result = num2 / num1;
                        break;
                }
                stack.push(""+result);
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

标签:num1,int,之栈,public,运算符,算法,数据结构,stack,表达式
来源: https://blog.csdn.net/oLengNuanZiZhi12/article/details/113803672