詳談棧的實現and幾個算法實現

    對於棧的概念以及圖解,在之前的文章中已經寫過了,而代碼卻沒有多少,恐理解膚淺,故代碼獻上,以求真知~(重新看數據結構算法C那本書,還有好些個經典算法。。。比如迷宮求解和漢諾塔,爭取一一實現)

<span style="font-family:KaiTi_GB2312;"><strong>1.棧的順序存儲實現:

/**

    * 堆棧在使用過程中所需的最大空間很難估計,

    * 因此,一般來說在構造堆棧時不應設定堆棧的最大容量。

    * 一種合理的做法和線性表的實現類似,

    * 先爲堆棧分配一個基本容量,

    * 然後在實際的使用過程中,

    * 當堆棧的空間不夠時再倍增存儲空間,這個過程所需的時間均攤到每個

    * 數據元素時間爲Θ (1),不會影響操作實現的時間複雜度。

*/

public class StackTest {

    public static void main(String args[]) {

        Stack stack = new Stack(10); //make new Stack

        stack.push(10);

        stack.push(20);

        stack.push(30);

        stack.push(30);

        while(!stack.isEmpty()){

            int value = stack.pop();

            System.out.println(value);

            System.out.println();

        }

    }

}


class Stack{

    private int maxSize;

    private int[] stackArray;

    private int top; //棧頂元素

    public Stack(int s){

        maxSize = s;

        stackArray = new int[maxSize];

        top = -1;

    }

    //返回堆棧的大小

    public int getSize(){

        return top + 1;

    }


    //判斷堆棧是否爲空

    public boolean isEmpty(){

        return top < 0;

    }


/**

    * push()方法中將top值增加1,

    * 使它指向原頂端數據項上面的一個位置,

    * 並在這個位置上存儲一個數據項。

    * 再次提醒,

    * top是在插入數據項之前遞增的。

    * @param i

*/


    //入棧

    public void push(int i){

        stackArray[++top] = i;

    }


/**

    * pop()方法返回top標識的數據項值,然後top - 1

    * 這個方法有效的從棧中移除數據項,雖然數據項仍然存在數組中

    * (直到有新的數據項壓入棧中覆蓋這個數據項),但不能再訪問了

    * @return

*/

    //出棧

    public int pop(){

        return stackArray[top--];

    }

}

2.1單詞逆序
  
public class NumInverte {

public static void main(String args[]){
        Scanner scanner = new Scanner(System.in);
        System.out.println("輸入要操作的數的數量");
        int stackSize = scanner.nextInt();
        Stack stack = new Stack(stackSize);
        System.out.println("輸入數字");
        for(int i = 0;i <= stack.getSize();i++){
            i = scanner.nextInt();
            stack.push(i);
        }
        System.out.println("數字逆序後輸出");
        while(!stack.isEmpty()) {
            System.out.println(stack.pop() + " ");
        }
    }
}
2.2後綴表達式
形如:
//計算6 5 2 3 + 8 * + 3 + *    ( (2 + 3) * 8 + 5 + 3 ) * 6
這個記法叫做後綴或者逆波蘭記法,計算這個問題的最佳算法是使用棧。
計算一個後綴表達式的時間是O(N),因爲對輸入的每個元素的處理都是由一些棧操作組成從而花費常數時間。
注意:當一個表達式以後綴記號給出時,沒有必要知道任何優先規則比中綴表達式更容易計算,不用優先考慮規則和括弧,表達式中的操作數和操作符就足以完成任務。
後綴表達式的計算規則:
從左到右掃描整個表達式,把每個操作符應用到其之前的兩個操作數,並計算結果。
import java.util.Stack;
//計算6 5 2 3 + 8 * + 3 + *    ( (2 + 3) * 8 + 5 + 3 ) * 6
/**
 * 計算後綴表達式,假定操作數都是常量
 * */
public class PostfixEvaluator {
 /** 棧 */
 private Stack<Integer> stack;
 /** 創建一個新棧 */
 public PostfixEvaluator() {
  stack = new Stack<Integer>();
 }
 /**
  * 從左到右掃描表達式,以此標識出每個符號(操作數或操作符)。如果是操作數, 則把它壓入棧中。如果是操作符,則從棧中彈出兩個元素,
  * 並把該操作符應用在這兩個元素上,然後把操作結果壓入棧中。 當到達表達式的末尾時,棧中所剩域的元素就是該表達式的計算結果。
  * @param expr 後綴表達式
  * @return int 後綴表達式的值
  * */
 public int evaluate(String expr){
  int op1 , op2 , result = 0;
  String operator;
  //將字符串分解. \\s匹配任何空白字符,包括空格、製表符、換頁符等。
  String[] takeoperator = expr.split("\\s");
  for(int i = 0 ; i < takeoperator.length ; i++){
   System.out.print(takeoperator[i]+" ");//輸出
   operator = takeoperator[i];
   if(isOperator(operator)){//判斷是操作符,則出棧兩個操作數  
                op2 = (stack.pop()).intValue();  
                op1 = (stack.pop()).intValue();  
                result = evalSingleOp (operator.charAt(0),op1,op2);//計算結果  
                stack.push(new Integer(result));//把計算結果壓入棧中  
            }else {  
                stack.push(new Integer(Integer.parseInt(operator)));//壓入操作數
            }
  }
  return result;
 }
 /**
  * 計算
  *
  * @param1 op1 第一個操作數
  * @prama2 op2第二個操作數
  * @return 計算的結果
  * */
 private int evalSingleOp(char operator, int op1, int op2) {
  int result = 0;
  switch (operator) {
  case '+':
   result = op1 + op2;
   break;
  case '-':
   result = op1 - op2;
   break;
  case '*':
   result = op1 * op2;
   break;
  case '/':
   result = op1 / op2;
   break;
  }
  return result;
 }
 /**
  * 判斷是否爲操作符
  *
  * @param token
  * @return boolean
  * */
 private boolean isOperator(String operator) {
  return operator.equals("+") || operator.equals("-")
      || operator.equals("*") || operator.equals("/");
 }
}
/*測試類
import java.util.Scanner;
public class PostfixEvaluatorTest {
 public static void main(String[] args) {
  String expression, again;
  int result;
  try {
   @SuppressWarnings("resource")
   Scanner in = new Scanner(System.in);
   do {
    PostfixEvaluator evaluator = new PostfixEvaluator();
    System.out.println("請輸入一個後綴表達式");
    expression = in.nextLine();
    result = evaluator.evaluate(expression);
    System.out.println();
    System.out.println("計算結果爲:" + result);
    System.out.println("計算另外一個表達式[Y/N]?:");
    again = in.nextLine();
    if (again.equalsIgnoreCase("n")) {
     System.out.println("計算退出!");
    }
    System.out.println();
   } while (again.equalsIgnoreCase("y"));
  } catch (Exception e) {
   e.printStackTrace();
   System.out.println("輸入異常,請正確輸入後綴表達式,並以空格區分");
  }
 }
}
下面對一些用的並不熟練的方法做下記錄:
1.charAt(int index)
    返回指定所引出的char值。索引範圍從0 -- length() -1。序列的第一個char值在索引0處,第二個索引在1處,以此類推。
2.intValue()
    將Integer類型轉化爲int類型
    這時候就不得不提到另一個方法:valueOf(),是將基本數據類型轉化爲String的static方法,有多個重載方法。
    String.valueOf(boolean b) : 將 boolean 變量 b 轉換成字符串
    String.valueOf(char c) : 將 char 變量 c 轉換成字符串
    String.valueOf(char[] data) : 將 char 數組 data 轉換成字符串
    String.valueOf(char[] data, int offset, int count) :
    將 char 數組 data 中 由 data[offset] 開始取 count 個元素 轉換成字符串
    String.valueOf(double d) : 將 double 變量 d 轉換成字符串
    String.valueOf(float f) : 將 float 變量 f 轉換成字符串
    String.valueOf(int i) : 將 int 變量 i 轉換成字符串
    String.valueOf(long l) : 將 long 變量 l 轉換成字符串
    String.valueOf(Object obj) : 將 obj 對象轉換成 字符串, 等於 obj.toString() 
</strong></span>


發佈了51 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章