鏈棧是棧的鏈式存儲結構,通常採用不帶頭結點的單鏈表實現。棧頂對應鏈表頭部,採用頭插法進行入棧、出棧操作,時間複雜度均為 O(1)。本文給出規範、完整的 C 語言實現,修正了原文中類型定義不一致、操作函數混用順序棧邏輯等問題。
typedef int ElemType; // 可根據需要改為其他類型
typedef struct Node {
ElemType data;
struct Node* next;
} LinkNode, *LinkStack; // LinkStack 即棧頂指針
LinkStack Init_LinkStack(void) {
return NULL; // 空棧棧頂指針為 NULL
}
int IsEmpty_LinkStack(LinkStack top) {
return top == NULL;
}
int Push_LinkStack(LinkStack* top, ElemType x) {
LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
if (!newNode) return 0; // 內存分配失敗
newNode->data = x;
newNode->next = *top;
*top = newNode;
return 1; // 成功
}
int Pop_LinkStack(LinkStack* top, ElemType* x) {
if (IsEmpty_LinkStack(*top)) return 0; // 棧空
LinkNode* temp = *top;
*x = temp->data;
*top = temp->next;
free(temp);
return 1;
}
int Top_LinkStack(LinkStack top, ElemType* x) {
if (IsEmpty_LinkStack(top)) return 0;
*x = top->data;
return 1;
}
void Destroy_LinkStack(LinkStack* top) {
LinkNode* p;
while (*top) {
p = *top;
*top = (*top)->next;
free(p);
}
}
void Print_LinkStack(LinkStack top) {
LinkNode* p = top;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main(void) {
LinkStack S = Init_LinkStack();
int val;
Push_LinkStack(&S, 10);
Push_LinkStack(&S, 20);
Push_LinkStack(&S, 30);
printf("棧內元素(頂到底):");
Print_LinkStack(S); // 輸出: 30 20 10
Top_LinkStack(S, &val);
printf("棧頂元素: %d\n", val); // 30
Pop_LinkStack(&S, &val);
printf("出棧: %d\n", val); // 30
printf("剩餘元素:");
Print_LinkStack(S); // 20 10
Destroy_LinkStack(&S);
return 0;
}
| 特性 | 鏈棧 | 順序棧 |
|---|---|---|
| 存儲結構 | 鏈表,動態分配 | 數組,固定大小或動態擴容 |
| 內存利用 | 無內部碎片,但有指針開銷 | 可能預留過多/不足,需擴容策略 |
| 訪問非棧頂元素 | O(n) 遍歷 | O(1) 下標隨機訪問 |
| 適用場景 | 大小難預估、頻繁增減、嵌入式受限環境 | 大小可預估、需高性能隨機訪問、緩存友好 |
Push_SqStack 等函數實際操作的是順序棧結構體,與鏈棧定義衝突。務必統一結構體定義與操作函數。掌握鏈棧核心邏輯——頭插法入棧、頭刪法出棧,並養成規範的錯誤處理習慣,即可靈活應對各類棧應用場景。