棧是一種特殊的線性表,其插入和刪除操作只允許在線性表的一端進行。
定義一個描述棧抽象的數據類型接口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();
}