資料結構之棧,資料結構

來源:互聯網
上載者:User

資料結構之棧,資料結構

數組、鏈表、樹等資料結構適用於儲存資料庫應用中的資料記錄,它們常常用於記錄那些現實世界的對象和活動的資料,便與資料的訪問:插入、刪除和尋找特定資料項目

而棧和隊列更多的是作為程式員的工具來使用。他們主要作為構思演算法的協助工具輔助,而不是完全的資料存放區工具。這些資料結構的生命週期比那些資料庫類型的結構要短很多。在程式操作執行期間它們才被建立,通常它們去執行某項特殊的任務,當任務完成後就被銷毀

棧和隊列的訪問是受限制的,即在特定時刻只有一個資料項目可以被讀取或刪除

棧和隊列是比數組和其他資料結構更加抽象的結構,是站在更高的層面對資料進行組織和維護

棧的主要機制可用數組來實現,也可以用鏈表來實現。優先順序隊列的內部實現可以用數組或者一種特別的樹——堆來實現。

 

先來瞭解棧的概念和執行個體,然後分別深入理解隊列和優先順序隊列

 

棧只允許訪問一個資料項目:即最後插入的資料。移除這個資料項目後才能訪問倒數第二個插入的資料項目。它是一種“後進先出”的資料結構。

棧最基本的操作是出棧(Pop)、入棧(Push),還有其他擴充操作,如查看棧頂元素,判斷棧是否為空白、是否已滿,讀取棧的大小等

下面我們就用數組來寫一個棧操作的封裝類

 

public class Stack {      private int size;                 //棧的大小      private int top;                  //棧頂元素的下標      private int [] stackArray;   //棧的容器           //建構函式      public Stack(int size){             stackArray = new int [size];             top = -1; //初始化棧的時候,棧內無元素,棧頂下標設為-1             this.size = size;      }           //入棧,同時,棧頂元素的下標加一      public void push(int elem){             stackArray[++top] = elem; //插入棧頂      }           //出棧,刪除棧頂元素,同時,棧頂元素的下標減一      public int pop(){             return stackArray[top--];      }           //查看棧頂元素,但不刪除      public int peek(){             return stackArray[top];      }           //判空      public boolean isEmpty(){             return (top == -1);      }           //判滿      public boolean isFull(){             return (top == size-1);      }     }

上例中,沒有對可能的異常進行處理,需要由編程人員保證程式的正確性,比如,才出棧前需要應該保證棧中有元素,在入棧前應保證棧沒有滿

                                                                            入棧操作

 

                                                                                                           出棧操作

 

棧通常用於解析某種類型的文本串。通常,文本串是用電腦語言寫的程式碼,而解析它們的程式就是編譯器

下面我們來用棧來實現一個經典的應用:分隔字元匹配。想一下在Eclipse編程時,如果我們寫的代碼中如果多了一個“{”,後者少了一個“}”,或者括弧的順序錯亂,都會報錯。接下來我們就用棧來類比這種分隔字元匹配

分隔字元匹配程式從字串中不斷地讀取程式,每次讀取一個字元,若發現它是左分隔字元({、[、(),將它壓入棧中。當讀到一個右分隔字元時()、]、}),彈出棧頂元素,並且查看它是否和該右分隔字元匹配。如果它們不匹配,則程式報錯。如果到最後一直存在著沒有被匹配的分隔字元,程式也報錯

我們來看下面這個正確的字串,在棧中的變化過程:

a{b(c[d]e)f}

 

所讀字元                  棧中內容

      a                                 空

      {                                  {

      b                                 {

      (                                  {(

      c                                 {(

      [                                  {([

      d                                 {([

      ]                                  {(

      e                                 {(

      )                                  {

      f                                  {

      }                                  空

最後出現的左分隔字元需要被最先匹配,這符合棧“後進先出”的規則

在本例中,要處理的是字元,所以需要對上面的Stack類進行修改,需要將存放元素的數組改為char類型,並把相關方法的參數類型改為char類型,其餘不變

 

public class Stack {      private int size;                 //棧的大小      private int top;                  //棧頂元素的下標      private char [] stackArray;       //棧的容器           //建構函式      public Stack(int size){             stackArray = new char [size];             top = -1; //初始化棧的時候,棧內無元素,棧頂下標設為-1             this.size = size;      }           //入棧,同時,棧頂元素的下標加一      public void push(char elem){             stackArray[++top] = elem; //插入棧頂      }           //出棧,刪除棧頂元素,同時,棧頂元素的下標減一      public char pop(){             return stackArray[top--];      }           //查看棧頂元素,但不刪除      public char peek(){             return stackArray[top];      }           //判空      public boolean isEmpty(){             return (top == -1);      }           //判滿      public boolean isFull(){             return (top == size-1);      }     }

然後寫一個類來封裝分隔字元匹配的操作:

 

public class BrecketChecker {           private String input;  //儲存待檢查的字串           //構造方法,接受待檢查的字串      public BrecketChecker(String in){             this.input = in;      }           //檢查分隔字元匹配的方法      public void check(){             int strLength = input.length();             Stack stack = new Stack(strLength);                         for(int i=0;i<strLength;i++){                                       char ch =input.charAt(i);  //一次擷取串中的單個字元                                       switch(ch){                           case '{' :                           case '[' :                           case '(' :                                   //如果為左分隔字元,壓入棧                                  stack.push(ch);                                  break;                           case '}' :                           case ']' :                           case ')' :                                  //如果為右分隔字元,與棧頂元素進行匹配                                  if(!stack.isEmpty()){                                         charchx = stack.pop();                                                                                 if((ch== '{' && chx != '}')||                                            (ch == '(' && chx != ')')||                                            (ch == '[' && chx != ']')                                         ){                                                System.out.println("匹配出錯!字元:"+ch+",下標:"+i);                                         }                                  }else{                                         System.out.println("匹配出錯!字元:"+ch+",下標:"+i);                                  }                                                            default :                                  break;                    }                                }                         if(!stack.isEmpty()){                    //匹配結束時如果棧中還有元素,證明右分隔字元缺失                    System.out.println("有括弧沒有關閉!");             }      }     }

 

測試類別

public static void main(String[] args) {                         System.out.println("輸入需要檢測的字串:");             String str = getString();             BrecketChecker checker = newBrecketChecker(str);             checker.check();      }           public static String getString(){             String str = "";             try{                    InputStreamReader reader =new InputStreamReader(System.in);                    BufferedReader bReader = newBufferedReader(reader);                    str = bReader.readLine();             }catch(IOException e){                    e.printStackTrace();             }             return str;      } 


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.