栈是一种特殊的线性表,其插入和删除操作只允许在线性表的一端进行。
定义一个描述栈抽象的数据类型接口SStack
public interface SStack<T> {
boolean isEmpty();
void push(T x);
T pop();
T get();
}
顺序栈的实现:
public class SeqStack<T> implements SStack<T> {
private Object[] element;
private int top;
public SeqStack(int size){
this.element = new Object[size];
this.top = -1;
}
public SeqStack(){
this(64);
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return top == -1;
}
@Override
public void push(T x) {
// TODO Auto-generated method stub
if(x == null)
return;
if(this.top == element.length - 1){
Object[] temp = this.element;
Object[] element = new Object[temp.length * 2];
for(int i = 0;i < temp.length;i ++){
element[i] = temp[i];
}
}
this.top ++;
element[this.top] = x;
}
@Override
public T pop() {
// TODO Auto-generated method stub
return this.top == -1 ? null : (T)element[top --];
}
@Override
public T get() {
// TODO Auto-generated method stub
return this.top == -1 ? null : (T)element[top];
}
}
链式栈的实现:
public class LinkedStack<T> implements SStack<T>{
private Node<T> top;
public LinkedStack(){
this.top = null;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return this.top == null;
}
@Override
public void push(T x) {
// TODO Auto-generated method stub
if(x != null)
this.top = new Node(x,this.top);
}
@Override
public T pop() {
// TODO Auto-generated method stub
if(this.top == null)
return null;
T temp = this.top.date;
this.top = this.top.next;
return temp;
}
@Override
public T get() {
// TODO Auto-generated method stub
return this.top == null ? null : this.top.date;
}
}
class Node<T>{
public T date;
public Node<T> next;
public Node(T date,Node<T> next){
this.date = date;
this.next = next;
}
public Node(){this(null,null);}
}
栈的应用,使用栈计算表达式的值
第一步,将中缀表达式转化为后缀表达式 ;
第二步,利用后缀表达式求值。
(1)将中缀表达式转化为后缀表达式
<1> 设置一个运算符栈,设置一个后缀表达式字符串;
<2> 读取字符串每一位依次处理,如果是数组就直接加到后缀字符串;如果是‘(’,则直接进栈;如果是‘)’,则若干运算符出栈,添加到后缀表达式之后;如果是运算符,查看运算符栈,如果运算符为空,直接入栈,如果不为空,比较当前字符与栈顶字符,如果当前字符优先级不高于栈顶字符,则栈顶字符出栈,加到后缀字符串后面,当前字符入栈,如果当前字符优先级高于栈顶字符,直接入栈。
<3> 字符串读取结束,将栈中运行符依次出栈,添加到后缀表达式之后。
public static String toPostfix(String expstr){
SeqStack<String> stack = new SeqStack<String>(expstr.length());
String postfix = "";
int i = 0;
while(i <expstr.length()){
char ch = expstr.charAt(i);
switch(ch){
case '+':
case '-': while(!stack.isEmpty() && !stack.get().equals("("))
postfix += stack.pop();
stack.push(ch + "");
i ++; break;
case '*':
case '/':while(!stack.isEmpty() && (stack.get().equals("*") || stack.get().equals("/")))
postfix += stack.pop();
stack.push(ch + "");
i ++; break;
case '(':stack.push(ch + "");
i ++; break;
case ')':String out = stack.pop();
while(out != null && !out.equals("(")){
postfix += out;
out = stack.pop();
}
i ++; break;
default : while(i < expstr.length() && ch >= '0' && ch <= '9'){
postfix += ch;
i ++;
if(i <expstr.length())
ch = expstr.charAt(i);
}
postfix += " ";
}
}
while(!stack.isEmpty())
postfix += stack.pop();
return postfix;
}
(2) 后缀表达式求值
<1> 设置一个操作数栈,依次处理已经得到的后缀表达式;
<2> 若得到的数字,先将其后连续若干数字转化为整数,再将该整数入栈;
<3> 若得到的是运算符,出栈两个值进行运算,运算结果入栈;
<4> 重复以上步骤,直至后缀表达式结束,栈中最后一个元素就是所求表达式的结果。
public static int value(String postfix){
SStack<Integer> stack = new LinkedStack<Integer>();
int i = 0,result = 0;
while(i < postfix.length()){
char ch = postfix.charAt(i);
if(ch >= '0' && ch <='9'){
result = 0;
while(ch != ' '){
result = result * 10 + Integer.parseInt(ch + "");
i ++;
ch = postfix.charAt(i);
}
i ++;
stack.push(new Integer(result));
}else{
int y = stack.pop().intValue();
int x = stack.pop().intValue();
switch(ch){
case '+' : result = x + y; break;
case '-' : result = x - y; break;
case '*' : result = x * y; break;
case '/' : result = x / y; break;
}
stack.push(new Integer(result));
i ++;
}
}
return stack.pop().intValue();
}