鏈棧和順序棧的區別在於,鏈棧不受空間限制,根據鏈表生成,如圖,首先觀察它的特點:
灰色表示真實數據,而top指向的結點,稱之為頭結點,它的數據項沒存入數據,僅僅是做為一個頭結點存在。在鏈棧的初始化中,首先創建了一個頭結點,但是里面沒有存放數據,如果可能,存放鏈棧的長度也是可以的。
如果初始化不創建頭結點,僅僅是將top=NULL,就省了一個頭結點。而,多了一個頭結點,計算的時候可能繞那么一點。反正,我不太習慣用這個頭結點。
接下來,是入棧操作,歸根到底還是單鏈表的細節操作,需要周轉幾步。這種手法在單鏈表的總結中會詳細記錄
鏈棧沒有特別要說的地方,如果單鏈表熟練,這個應該不會有大問題,而問題在於,這種代碼很容易前學后忘!
/*-----此鏈表帶有頭結點-------*/ /*-----可以改成不帶頭結點,更簡練一些*/ #include <iostream> using namespace std; #define OK 1 #define ERROR 0 typedef struct node { int data; struct node *next; }*ListStack,stack; void InitStack(ListStack &L)/*初始化*/ { L=(ListStack)malloc(sizeof(stack)); if(!L) exit(-1); L->next=NULL; } int PushStack(ListStack &top,int e)/*入棧!此創建帶頭結點*/ { ListStack p; if((p=(ListStack)malloc(sizeof(stack)))==NULL) exit(-1); p->data=e; p->next=top->next; top->next=p; return OK; } int PopStack(ListStack &top,int &e) /*出棧*/ { ListStack p;/*輔助指針p*/ p=top->next; if(!p) { cout<<"棧已空!"<<endl; return ERROR; } e=p->data; top->next=p->next; free(p); return OK; } void Traverse(ListStack &top)/*遍歷,打印*/ { ListStack p=top->next; while(p) { cout<<p->data<<" "; p=p->next; }; } void DestoryStack(ListStack &top)/*銷毀*/ { if(top->next) { DestoryStack(top->next);/*采用遞歸方式銷毀*/ free(top->next); top->next=NULL; } } int main(void) { int e; ListStack top; InitStack(top);/*初始化*/ PushStack(top,23);/*入棧*/ PushStack(top,20);/*入棧*/ PushStack(top,15);/*入棧*/ Traverse(top);/*遍歷打印*/ PopStack(top,e);/*出棧*/ DestoryStack(top);/*銷毀棧*/ return 0; }
補充:上面所說的頭結點可以專門用一個結構體包括,其中包含一個top指針和計數count,方法如下:
先定義結點結構:
typedef struct node { int data; struct node *next; }*LinkStackPtr,Node;
接着再定義頭結點:
typedef struct LinkStack { LinkStackPtr top; int count; }LinkStack;
這樣,頭結點就比較獨立,而且里面還包含一個計數功能
/*————————————————————————————*/