本章我們介紹有關棧的知識,棧的重點在於順序存儲,鏈式存儲及其特點。
1.棧的基本概念
(1)棧的定義
棧是只允許在一端進行插入和刪除的線性表。有一個棧頂和棧底。棧頂是允許插入和刪除的那一端,棧底是不允許插入和刪除的那一端。如果一個棧不包括任何元素,就是一個空表也就是空棧。
棧的特點是先進先出。
(2)棧的基本操作
棧的基本操作包括下面六種:
InitStack(&S):初始化一個空棧S。
StackEmpty(S):判斷一個棧是否為空。
Push(&S,x):進棧,若棧未滿,則將x加入使其成為新棧頂。
Pop(&S,&x):出棧,若棧非空,則彈出棧頂元素,並用x返回。
GetTop(S,&x):得到棧頂元素,若棧S非空,則用x返回棧頂元素。
DestoryStack(&S):銷毀棧,並釋放棧S占用的存儲空間("&"表示引用調用)。
2.棧的順序存儲結構
棧是一種特殊的線性表,有兩種存儲方式,這里先介紹順序存儲結構。
(1)順序棧的實現
采用順序存儲的棧叫做順序棧,它用一組地址連續的存儲單元存放自棧底到棧頂的數據元素,同時附設一個指針top指示當前棧頂元素的位置。
棧的順序存儲類型定義為:
#define MaxSize 50 //定義棧中元素的最大個數
typedef struct{
ElemType data[MaxSize]; //存放棧中的元素
int top; //棧頂指針
}SqStack
要注意的是,初始時把棧頂指針S.top(S是SqStack的簡化)設置為-1或者0,棧頂元素為S.data[S.top]。
進棧的時候,棧如果不滿,則先把棧頂指針加1,再把值送到棧頂元素位置。出棧的時候,棧如果非空,先取棧頂元素值,再將棧頂元素減1.
如果初始時把棧頂指針S.top設置為-1,則判斷棧空的條件是S.top-1,棧滿的條件為S.topMaxSize-1,棧長是S.top+1。
由於入棧操作受到數組大小的限制,當對棧的最大使用空間估計不足的時候,有可能發生棧上溢,此時應該及時處理,避免出錯。
(2)順序棧的基本運算
初始化順序棧
void InitStack(SqStack &S){
S.top = -1;
}
棧空的判斷
bool StackEmpty(SqStack S){
if(S.top == -1)
return true;
else
return false;
}
進棧
bool Push(SqStack &S,ElemType x){
if(S.top == MaxSize - 1)
return false;
S.data[++S.top] = x;
return true;
}
出棧
bool Pop(SqStack &S,ElemType &x){
if(S.top == -1)
return false;
x = S.data[S.top--];
return true;
}
讀棧頂元素
bool GetTop(SqStack S,ElemType &x){
if(S.top == -1)
return false;
x = S.data[S.top];
return true;
}
(3)順序棧的注意事項
前面的順序棧的操作是在順序棧的棧頂指針S.top設置為-1時的算法。如果把S.top設置為0,即top指向棧頂元素的下一個位置,則入棧操作變為S.data[S.top++] = x;出棧操作變為x = S.data[--S.top],對應的棧空條件變為S.top = 0,棧滿條件為S.top = MaxSize。
3.棧的鏈式存儲結構
采用鏈式存儲的棧稱為鏈棧,優點是便於多個棧共享存儲空間和提高其效率,且不存在棧滿上溢的情況。通常采用單鏈表實現,規定所有操作在單鏈表的表頭進行,相當於棧頂。這里設定鏈棧沒有頭結點,Lhead頭指針直接指向棧頂元素。站的鏈式存儲類型為:
typedef struct Linknode{
ElemType data;
struct Linknode *next;
}*LiStack;
