堆棧也能夠採用鏈式存儲結構,稱爲鏈棧。鏈棧常採用單鏈表表示。其實現是將鏈表的表頭做爲棧頂實現,這樣就不須要在單鏈表中增長頭結點,棧頂指針就是鏈表的頭指針。node
下面的代碼實現了鏈棧的相關操做,其中有個錯誤關於重複申請堆空間讓我鬱悶了會兒,不事後來找出來了。函數
#include <stdio.h> #include <stdlib.h> typedef struct node { char data; struct node *next; }linkstack; linkstack * Linkstack_Create(); //建立鏈棧 char Linkstack_GetTop(linkstack *q); //取得棧頂 linkstack *Linkstack_In(linkstack *q, char dat); //入棧 linkstack * Linkstack_Out(linkstack *q, char *dat); //出棧 void Linkstack_SetNull(linkstack *q); //置空棧 int Linkstack_Empty(linkstack *q); //棧是否爲空 void ShowLinkstack(linkstack *q); //輸出顯示棧 int main(void) { linkstack *q; int choice, ans; char dat; printf("鏈棧的操做練習:\n"); printf("請依次輸入鏈棧字符數據('#'號表示結束):\n"); q = Linkstack_Create(); getchar(); while(1) { printf("鏈棧操做:\n"); printf("1.取得棧頂結點\n"); printf("2.入棧\n"); printf("3.出棧\n"); printf("4.輸出顯示鏈棧\n"); printf("5.退出程序\n"); printf("作出選擇:"); scanf("%d", &choice); getchar(); //消除回車爲後面帶來的影響 switch(choice) { case 1: dat = Linkstack_GetTop(q); if(dat == '\0') printf("取得頭結點失敗!\n"); else printf("頭結點爲%c\n", dat); break; case 2: printf("輸入想入棧的字符:\n"); dat = getchar(); q = Linkstack_In(q, dat); break; case 3: q = Linkstack_Out(q, &dat); if(dat != '\0') printf("出棧的字符爲%c\n", dat); break; case 4: printf("輸出的字符依次爲:\n"); ShowLinkstack(q); break; case 5: return 0; break; default: printf("選擇無效!\n"); break; } } return 1; } //鏈棧置空 void Linkstack_SetNull(linkstack *q) { linkstack *s; while(q != NULL) //鏈棧置空時須要釋放每一個結點的空間 { s = q; q = q->next; free(s); } } //判斷鏈棧是否爲空 int Linkstack_Empty(linkstack *q) { if(q == NULL) return 1; else return 0; } //建立鏈棧 linkstack * Linkstack_Create() { linkstack *q = NULL; char ch; Linkstack_SetNull(q); ch = getchar(); while(ch != '#') { // q = (linkstack*)malloc(sizeof(linkstack)); //此句又讓人糾結了很久,有此句時建立的鏈棧只有棧頂字符,申請了兩次空間(下面入棧函數中一次),至於爲何會形成這種結果,暫時不知道- -!! q = Linkstack_In(q, ch); ch = getchar(); } return q; } //取得棧頂結點 char Linkstack_GetTop(linkstack *q) { if(Linkstack_Empty(q)) //先要判斷棧頂是否爲空 return '\0'; else return q->data; } //入棧,返回棧頂結點指針 linkstack *Linkstack_In(linkstack *q, char dat) { linkstack *e; e = (linkstack*)malloc(sizeof(linkstack)); e->data = dat; e->next = q; return e; } //出棧,返回棧頂結點指針 linkstack *Linkstack_Out(linkstack *q, char *dat) { linkstack *s; if(Linkstack_Empty(q)) //先要判斷棧頂是否爲空 { *dat = '\0'; return NULL; } else { *dat = q->data; s = q; q = q->next; free(s); return q; } } //輸出顯示鏈棧,從棧頂到棧底 void ShowLinkstack(linkstack *q) { linkstack *s; s = q; while(s != NULL) { putchar(s->data); putchar(' '); s = s->next; } printf("\n"); }