棧(Stack)是限定只能在表的一端進行插入和刪除操作的線性表。在表中,允許插入和刪除的一端稱作“棧頂(top)”,不允許插入和刪除的另一端稱作“棧底(bottom)”。
通常稱往棧頂插入元素的操作為“入棧”,稱刪除棧頂元素的操作為“出棧”。因為後入棧的元素先於先入棧的元素出棧,故被稱為是一種“後進先出”的結構,因此又稱 LIFO 表(Last In First Out的縮寫)。
和線性表類似,棧也有兩種儲存表示:順序棧和鏈棧。
順序儲存結構簡稱為順序棧。和順序表類似,對順序棧也需要事先為它分配一個可以容納最多元素的儲存空間。用圖表示順序棧如下:
鏈棧即為棧的鏈式儲存結構。
順序棧的實現依靠數組,而數組需要事先聲明長度,一次性地靜態地分配記憶體空間。這樣就給我們帶來很多不便。因為我們事先並不能精確地估計棧所需的大小,估計大了浪費空間,估計小了後果就嚴重了,導致程式無法正常運行。所以我們通常使用鏈棧這種資料結構。
鏈棧用鏈表作為儲存結構,棧初始化時僅需給棧頂指標分配記憶體空間,而後每當有資料入棧時再為該資料分配空間,這樣實現了記憶體空間的動態分配。理論上棧的大小可以是無限大的(小心撐爆你的記憶體 o(∩_∩)o)。不存在順序棧的諸多問題。
程式實現:依次把0~99壓棧,再依次出棧並列印。
程式清單:LinkStack.h LinkStackTest.c
LinkStack.h
/* LinkStack.h */
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define NULL 0
typedef int ElementType;
typedef struct node {
ElementType data;
struct node *next;
}StackNode, *LinkStack;
void InitStack(LinkStack top) {
top->next = NULL;
}
int IsEmpty(LinkStack top) {
if(top->next == NULL) return TRUE;
return FALSE;
int Push(LinkStack top, ElementType element) {
StackNode *temp;
temp = (StackNode *)malloc(sizeof(StackNode));
if(temp == NULL) return FALSE;
temp->data = element;
temp->next = top->next;
top->next = temp;
return TRUE;
}
int Pop(LinkStack top, ElementType *element) {
if(IsEmpty(top)) return FALSE;
StackNode *temp = top->next;
*element = temp->data;
top->next = temp->next;
free(temp);
return TRUE;
void GetTop(LinkStack top, ElementType *element) {
*element = top->next->data;
}
LinkStackTest.c
/* LinkStackTest.c */
#include <stdio.h>
#include "LinkStack.h"
void main() {
LinkStack s;
s = (LinkStack)malloc(sizeof(StackNode));
InitStack(s);
for(int i=0; i<100; i++)
Push(s,i);
int rslt;
while (!IsEmpty(s)) {
Pop(s,&rslt);
printf("%d ",rslt);
}
}
}