一、简介
1.栈是一个“先入后出”的有序列表。
2.栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表,允许插入和删除的一端为变化的一端,成为栈顶,另一端为固定的一端,成为栈底。
3.根据栈的特点可知,最先放入栈中的元素在栈底,最后放入的元素在栈顶,而删除恰好相反,最后放入的元素先删除,最先放入的元素后删除。
二、应用实例
1.用数组模拟栈的基本操作
package Stack; import java.util.Random; class Stack{ private int maxsize; private int[] stack; int top=-1; public Stack(int maxsize) { this.maxsize = maxsize; stack=new int[maxsize]; } public boolean isFull(){ return top==maxsize-1; } public boolean isEmpty(){ return top==-1; } public void pop(int value){ if(isFull()){ throw new RuntimeException ("栈已满,无法继续添加元素"); } stack[++top]=value; } public int push(){ if(isEmpty ()){ throw new RuntimeException ("栈为空,无法取出元素"); } int value=stack[top]; top--; return value; } public void list(){ if(isEmpty ()){ throw new RuntimeException ("栈为空"); } for(int i=top;i>=0;i--){ System.out.println (stack[i] ); } } } public class StackTest { public static void main(String[] args) { Stack stack = new Stack (5); for (int i=0;i<5;i++){ stack.pop(new Random ().nextInt (10)); } stack.list(); System.out.println ( stack.push ()); System.out.println ( ); stack.list(); } }
2.数学表达式的计算(只十以内包含加减乘除的四则运算)
解答思路:
通过一个index索引遍历我们的表达式
若果发现是一个数字则直接入数栈
如果发现是一个符号,并且符号栈为空,则就直接入符号栈;
如果符号栈不为空,进行操作符优先级的比较,如果当前操作符的优先级小于或等于栈中的操作符,就需要从数栈中pop两个数,并且从符号栈中再pop出一个符号对两个数进行计算,并将计算的结果存入到数栈中,然后将当前操作符存入符号栈中,如果当前运算符的优先级大于栈中的运算符,则就直接进入符号栈
当表达式扫描完成后,就顺序从数栈和符号栈中pop出相应的数字和操作符,并运行
最后数栈就只有一个数字,就是当前表达式的结果
package Stack; import java.util.Scanner; class Stack2{ private int maxsize; private int[] stack2; int top=-1; public Stack2(int maxsize) { this.maxsize = maxsize; stack2=new int[maxsize]; } public boolean isFull(){ return top==maxsize-1; } public boolean isEmpty(){ return top==-1; } public void push(int value){ if(isFull()){ throw new RuntimeException ("栈已满,无法继续添加元素"); } stack2[++top]=value; } public int pop(){ if(isEmpty ()){ throw new RuntimeException ("栈为空,无法取出元素"); } int value=stack2[top]; top--; return value; } public void list(){ if(isEmpty ()){ throw new RuntimeException ("栈为空"); } for(int i=top;i>=0;i--){ System.out.println (stack2[i] ); } } //返回栈的优先级,优先级是程序员进行确定的,规定优先级使用数字表示,数字越大,优先级越高 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 peek(){ return stack2[top]; } public void setTop(int top) { this.top = top; } public int cal(int num1, int num2, int oper){ int res=0; switch(oper){ case '+': res=num2+num1; break; case '-': res=num2-num1; break; case '*': res=num2*num1; break; case '/': try { res=num2/num1; } catch (Exception e) { e.printStackTrace ( ); } finally { } break; default:break; } return res; } } public class Calculator { public static void main(String[] args) { Scanner sc = new Scanner (System.in); System.out.println ("请输入表达式:" ); String str=sc.nextLine (); int index=0; int oper=0; int num1=0; int num2=0; Stack2 numStack = new Stack2 (10); Stack2 operStack = new Stack2 (10); while (true){ char ch= str.charAt (index); if(operStack.isOper (ch)) { if (!operStack.isEmpty ( )) { if (operStack.priority (ch) <= operStack.priority (operStack.peek ( ))) { num1 = numStack.pop ( ); num2 = numStack.pop ( ); oper = operStack.pop ( ); int 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); } index++; if(index>=str.length ()){ break; } } System.out.println ( ); while(true){ if(operStack.isEmpty ()){ break; } num1=numStack.pop (); num2=numStack.pop(); oper=operStack.pop(); int res=numStack.cal (num1,num2,oper); numStack.push(res); } int res=numStack.pop (); System.out.printf("表达式的结果为:%d",res ); } }