1. 程式人生 > >棧定義及其基本操作,順序棧和鏈棧

棧定義及其基本操作,順序棧和鏈棧

 棧和佇列是兩種特殊的線性表,它們的邏輯結構和線性表相同,只是其運算規則較線性表有更多的限制,故又稱它們為運算受限的線性表。棧和佇列被廣泛應用於各種程式設計中。

棧的定義及基本運算
1、棧的定義
     棧(Stack)是限制僅在表的一端進行插入和刪除運算的線性表。
  (1)通常稱插入、刪除的這一端為棧頂(Top),另一端稱為棧底(Bottom)。
  (2)當表中沒有元素時稱為空棧
  (3)棧為後進先出(Last In First Out)的線性表,簡稱為LIFO表
     棧的修改是按後進先出的原則進行。每次刪除(退棧)的總是當前棧中"最新"的元素,即最後插入(進棧)的元素,而最先插入的是被放在棧的底部,要到最後才能刪除。




  【示例】元素是以a1,a2,…,an的順序進棧,退棧的次序卻是an,an-1,…,a1

2、棧的基本運算
(1)InitStack(S)
     構造一個空棧S。
(2)StackEmpty(S)
     判棧空。若S為空棧,則返回TRUE,否則返回FALSE。
(3)StackFull(S)
     判棧滿。若S為滿棧,則返回TRUE,否則返回FALSE。
注意:
     
該運算只適用於棧的順序儲存結構。
(4)Push(S,x)
     進棧。若棧S不滿,則將元素x插入S的棧頂。
(5)Pop(S)
     退棧。若棧S非空,則將S的棧頂元素刪去,並返回該元素。
(6)StackTop(S)
     取棧頂元素。若棧S非空,則返回棧頂元素,但不改變棧的狀態。

順序棧

     棧的順序儲存結構簡稱為順序棧,它是運算受限的順序表。
1、 順序棧的型別定義
  #define StackSize 100 //假定預分配的棧空間最多為100個元素
  typedef char DataType;//假定棧元素的資料型別為字元
  typedef struct{
      DataType data[StackSize];
      int top;
     }SeqStack; 
  注意:
   
①順序棧中元素用向量存放
     ②棧底位置是固定不變的,可設定在向量兩端的任意一個端點
     ③棧頂位置是隨著進棧和退棧操作而變化的,用一個整型量top(通常稱top為棧頂指標)來指示當前棧頂位置,top指向-1,即頂端儲存單元地址的前一位,加1指向第一個單元,代表含有一個元素!
2、 順序棧的基本操作

 前提條件:
     設S是SeqStack型別的指標變數。若棧底位置在向量的低端,即S->data[0]是棧底元素。
(1) 進棧操作
     進棧時,需要將S->top加1
  注意:
     ①S->top==StackSize-1表示棧滿
  ②"上溢"現象--當棧滿時,再做進棧運算產生空間溢位的現象。
      上溢是一種出錯狀態,應設法避免。

(2) 退棧操作
     退棧時,需將S->top減1
  注意:
     
①S->top<0表示空棧
     ②"下溢"現象——當棧空時,做退棧運算產生的溢位現象。
      下溢是正常現象,常用作程式控制轉移的條件。
順序棧在進棧和退棧操作時的具體變化情況【參見動畫演示

3、順序棧的基本運算
(1) 置棧空
  void InitStack(SeqStack *S)
    {//將順序棧置空
        S->top=-1;
    } 

(2) 判棧空

  int StackEmpty(SeqStack *S)
    {
        return S->top==-1;
    }

(3) 判棧滿
  int StackFull(SeqStack *SS)
     {
       return S->top==StackSize-1;
     }

(4) 進棧
  void Push(S,x)
     {
       if (StackFull(S))
             Error("Stack overflow"); //上溢,退出執行
       S->data[++S->top]=x;//棧頂指標加1後將x入棧
     }

(5) 退棧
  DataType Pop(S)
    {
      if(StackEmpty(S))
           Error("Stack underflow"); //下溢,退出執行
      return S->data[S->top--];//棧頂元素返回後將棧頂指標減1
    }

(6) 取棧頂元素
  DataType StackTop(S)
    {
       if(StackEmpty(S))
           Error("Stack is empty");
       return S->data[S->top];
     }

4、兩個棧共享同一儲存空間
     當程式中同時使用兩個棧時,可以將兩個棧的棧底設在向量空間的兩端,讓兩個棧各自向中間延伸。當一個棧裡的元素較多,超過向量空間的一半時,只要另一個棧的元素不多,那麼前者就可以佔用後者的部分儲存空間。
    只有當整個向量空間被兩個棧佔滿(即兩個棧頂相遇)時,才會發生上溢。因此,兩個棧共享一個長度為m的向量空間和兩個棧分別佔用兩個長度為 └ m/2┘和┌m/2┐的向量空間比較,前者發生上溢的概率比後者要小得多。
    
     具體方法【參見動畫演示