栈的基本机构
1、栈典型的结构,先进者后出,后进者先出,从操作特性上来看,栈是一种“操作受限”的线性表,只允许在一端插入和删除数据。
2、用数组实现的栈叫做顺序栈,用链表实现的栈,我们叫做链式栈;
栈的简单实现:
// 基于数组实现的顺序栈
public class ArrayStack {
private String[] items; // 数组
private int count; // 栈中元素个数
private int n; // 栈的大小
// 初始化数组,申请一个大小为 n 的数组空间
public ArrayStack(int n) {
this.items = new String[n];
this.n = n;
this.count = 0;
}
// 入栈操作
public boolean push(String item) {
// 数组空间不够了,直接返回 false,入栈失败。
if (count == n) return false;
// 将 item 放到下标为 count 的位置,并且 count 加一
items[count] = item;
++count;
return true;
}
// 出栈操作
public String pop() {
// 栈为空,则直接返回 null
if (count == 0) return null;
// 返回下标为 count-1 的数组元素,并且栈中元素个数 count 减一
String tmp = items[count-1];
--count;
return tmp;
}
}
3、入栈和出栈的空间复杂度是O(1),时间复杂度也是O(1)
4、栈在函数调用中的应用,比较经典的应用场景就是函数调用栈
笔者利用Java栈写了一个简单的计算字符串表达式的程序:、
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
/**
* @author haochajin
* @version : CalculateString.java, v 0.1 2019-09-11 10:37
*/
public class CalculateString {
private static double calTwoNumbers(char ch, double a, double b) {
if(ch == '+'){
return b + a;
} else if(ch == '-') {
return b - a;
}else if(ch == '*') {
return b * a;
}else if(ch == '/') {
return b / a;
}
return 0;
}
private static double calExp(String exp){
Stack<Double> numStack = new Stack<>();
Stack<Character> oprStack = new Stack<>();
Map<Character,Integer> oprMap = new HashMap<>();
oprMap.put('+',1);
oprMap.put('-',1);
oprMap.put('*',2);
oprMap.put('/',2);
for (int i=0; i<exp.length(); i++){
char ch = exp.charAt(i);
if(Character.isDigit(ch)) {
numStack.push(Double.valueOf(ch - '0'));
} else if (oprMap.containsKey(ch)){
if(oprStack.empty() || oprMap.get(ch) > oprMap.get(oprStack.peek())){
oprStack.push(ch);
}else {
while (!oprStack.empty() && oprMap.get(ch) <= oprMap.get(oprStack.peek())){
double a = numStack.pop();
double b = numStack.pop();
numStack.push(calTwoNumbers(oprStack.pop(),a,b));
}
oprStack.push(ch);
}
}
}
while (!oprStack.empty()){
double a = numStack.pop();
double b = numStack.pop();
numStack.push(calTwoNumbers(oprStack.pop(),a,b));
}
return numStack.pop();
}
public static void main(String[] args) throws ScriptException {
String exp = "3/5*2-5/1*2+6*6";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object ob = engine.eval(exp);
System.out.println(calExp(exp));
System.out.println(ob);
}
}