堆疊（stack）又稱為棧或 zhcn 堆疊；zhtw 堆疊；，是計算機科學中的一種抽象資料型別，只允許在有序的線性資料集合的一端（稱為堆疊頂端，top）進行加入資料（push）和移除資料（pop）的運算。因而按照後進先出（LIFO Last In First Out）的原理運作，堆疊常用一維陣列或連結串列來實現。常與另一種有序的線性資料集合佇列相提並論。 操作 堆疊使用兩種基本操作：推入（壓棧，push）和彈出（彈棧，pop）： 推入：將資料放入堆疊頂端，堆疊頂端移到新放入的資料。 彈出：將堆疊頂端資料移除，堆疊頂端移到移除後的下一筆資料。 上面就是棧最核心的兩個基本操作，可以在棧的視覺化頁面中直觀理解這裡的操作。棧的視覺化頁面：線上視覺化演示棧的各種操作 特點 堆疊的基本特點： 先入後出，後入先出。 除頭尾節點之外，每個元素有一個前驅，一個後繼。 抽象定義 以下是堆疊的 VDM：Jones Systematic Software Development Using VDM 函式簽名： init Stack push N x Stack Stack top Stack N cup ERROR pop Stack Stack isempty Stack Boolean 此處的 N 代表某個元素（如自然數），而 cup 表示集合求並。 語義： top init ERROR top push is i pop init init pop push i s s isempty init true isempty push i s false 軟體堆疊 堆疊可以用陣列和連結串列兩種方式實現，一般為一個堆疊預先分配一個大小固定且較合適的空間並非難事，所以較流行的做法是 Stack 結構下含一個數組。如果空間實在緊張，也可用連結串列實現，且去掉表頭。 這裡的例程是以 C 語言實現的。 陣列堆疊 儲存結構 c31h 棧的順序儲存表示 define STACK_INIT_SIZE 10 儲存空間初始分配量 define STACK_INCREMENT 2 儲存空間分配增量 typedef struct SqStack SElemType base 在棧構造之前和銷燬之後，base 的值為 NULL SElemType top 棧頂指標 int stacksize 當前已分配的儲存空間，以元素為單位 SqStack 順序棧 基本操作 bo31c 順序棧 儲存結構由 c31h 定義 的基本操作 9 個 void InitStack SqStack S 構造一個空棧 S SbaseSElemType malloc STACK_INIT_SIZEsizeof SElemType if Sbase exit OVERFLOW 儲存分配失敗 StopSbase SstacksizeSTACK_INIT_SIZE void DestroyStack SqStack S 銷燬棧 S，S 不再存在 free Sbase SbaseNULL StopNULL Sstacksize0 void ClearStack SqStack S 把 S 置為空棧 StopSbase Status StackEmpty SqStack S 若棧 S 為空棧，則返回 TRUE，否則返回 FALSE if StopSbase return TRUE else return FALSE int StackLength SqStack S 返回 S 的元素個數，即棧的長度 return StopSbase Status GetTop SqStack SSElemType e 若棧不空，則用 e 返回 S 的棧頂元素，並返回 OK；否則返回 ERROR if StopSbase eStop1 return OK else return ERROR void Push SqStack SSElemType e 插入元素 e 為新的棧頂元素 if StopSbaseSstacksize 棧滿，追加儲存空間 SbaseSElemType realloc SbaseSstacksizeSTACK_INCREMENTsizeof SElemType if Sbase exit OVERFLOW 儲存分配失敗 StopSbaseSstacksize SstacksizeSTACK_INCREMENT Stope Status Pop SqStack SSElemType e 若棧不空，則刪除 S 的棧頂元素，用 e 返回其值，並返回 OK；否則返回 ERROR if StopSbase return ERROR eStop return OK void StackTraverse SqStack Svoid visitSElemType 從棧底到棧頂依次對棧中每個元素呼叫函式 visit while StopSbase visit Sbase printf n 串列堆疊 儲存結構 c22h 線性表的單鏈表儲存結構 struct LNode ElemType data struct LNode next typedef struct LNode LinkList 另一種定義 LinkList 的方法 基本操作 bo35c 鏈棧 儲存結構由 c22h 定義 的基本操作 4 個 部分基本操作是由 bo28cpp 中的函式改名得來 另一部分基本操作是由呼叫 bo28cpp 中的函式 取特例 得來 typedef SElemType ElemType 棧結點型別和連結串列結點型別一致 includec22h 單鏈表儲存結構 typedef LinkList LinkStack LinkStack 是指向棧結點的指標型別 define InitStack InitList InitStack 與 InitList 作用相同，下同 define DestroyStack DestroyList define ClearStack ClearList define StackEmpty ListEmpty define StackLength ListLength includebo28c 無頭結點單鏈表的基本操作 Status GetTop LinkStack SSElemType e 若棧不空，則用 e 返回 S 的棧頂元素，並返回 OK；否則返回 ERROR return GetElem S1e Status Push LinkStack SSElemType e 插入元素 e 為新的棧頂元素 return ListInsert S1e Status Pop LinkStack SSElemType e 若棧不空，則刪除 S 的棧頂元素，用 e 返回其值，並返回 OK；否則返回 ERROR return ListDelete S1e void StackTraverse LinkStack Svoid visitSElemType 從棧底到棧頂依次對棧中每個元素呼叫函式 visit LinkStack temppS p 指向棧頂元素 InitStack temp 初始化臨時棧 temp while p Push temppdata 由 S 棧頂到棧底，依次將棧元素入棧到 temp 棧 ppnext ListTraverse tempvisit 遍歷 temp 線性表 連結串列基本操作 bo28c 不帶頭結點的單鏈表 儲存結構由 c22h 定義 的部分基本操作 9 個 define DestroyList ClearList DestroyList 和 ClearList 的操作是一樣的 void InitList LinkList L 操作結果：構造一個空的線性表 L LNULL 指標為空 void ClearList LinkList L 初始條件：線性表 L 已存在。操作結果：將 L 重置為空表 LinkList p while L L 不空 pL p 指向首元結點 LLnext L 指向第 2 個結點 新首元結點 free p 釋放首元結點 Status ListEmpty LinkList L 初始條件：線性表 L 已存在。操作結果：若 L 為空表，則返回 TRUE，否則返回 FALSE if L return FALSE else return TRUE int ListLength LinkList L 初始條件：線性表 L 已存在。操作結果：返回 L 中資料元素個數 int i0 LinkList pL while p p 指向結點 沒到表尾 ppnext p 指向下一個結點 i return i Status GetElem LinkList Lint iElemType e L 為不帶頭結點的單鏈表的頭指標。當第 i 個元素存在時，其值賦給 e 並返回 OK，否則返回 ERROR int j1 LinkList pL if i1 i 值不合法 return ERROR while jnext if ji 存在第 i 個元素 epdata return OK else return ERROR int LocateElem LinkList LElemType eStatus compareElemTypeElemType 初始條件：線性表 L 已存在，compare 是資料元素判定函式 滿足為 1，否則為 0 操作結果：返回 L 中第 1 個與 e 滿足關係 compare 的資料元素的位序。 若這樣的資料元素不存在，則返回值為 0 int i0 LinkList pL while p i if compare pdatae 找到這樣的資料元素 return i ppnext return 0 Status ListInsert LinkList Lint iElemType e 在不帶頭結點的單鏈線性表 L 中第 i 個位置之前插入元素 e int j1 LinkList pLs if i1 i 值不合法 return ERROR sLinkList malloc sizeof struct LNode 生成新結點 sdatae 給 s 的 data 域賦值 if i1 插在表頭 snextL Ls 改變 L else 插在表的其餘處 while pjnext j if p i 大於表長 1 return ERROR snextpnext pnexts return OK Status ListDelete LinkList Lint iElemType e 在不帶頭結點的單鏈線性表 L 中，刪除第 i 個元素，並由 e 返回其值 int j1 LinkList pLq if i1 刪除第 1 個結點 Lpnext L 由第 2 個結點開始 epdata free p 刪除並釋放第 1 個結點 else while pnextjnext j if pnextji1 刪除位置不合理 return ERROR qpnext 刪除並釋放結點 pnextqnext eqdata free q return OK void ListTraverse LinkList Lvoid viElemType 初始條件：線性表 L 已存在。操作結果：依次對 L 的每個資料元素呼叫函式 vi LinkList pL while p vi pdata ppnext printf n 堆疊有時候也常用來指代堆疊段。 硬體堆疊 架構層次上的堆疊通常被用以申請和訪問記憶體。 硬體支援 大多數 CPU 都有用作堆疊指標的暫存器。 堆疊的應用 回溯法 遞迴 深度優先搜尋 參考文獻 參見 連結串列 佇列 Category 資料結構 Category 抽象資料型別 Category 帶有虛擬碼示例的條目