數據結構 第6講 鏈棧
進出的一端稱爲棧頂(top),另一端稱爲棧底(base)。棧可以用順序存儲,也可以用鏈式存儲。順序棧和鏈棧圖解:
順序棧是分配一段連續的空間,需要兩個指針,base指向棧底,top指向棧頂。而鏈棧每個結點的地址是不連續的,只需要一個棧頂指針即可。
從上圖可以看出,鏈棧的每個結點都包含兩個域,數據域和指針域,是不是和單鏈表一模一樣?那麼我們就可以按單鏈表的定義。
鏈棧的結構體定義:
鏈棧的結點定義和單鏈表一樣,只不過它只能在棧頂操作而已。
下面講解鏈棧的初始化、入棧,出棧,取棧頂元素等操作(元素以int類型爲例)。
1. 鏈棧初始化
初始化一個空棧,只需要讓棧頂指針爲空即可。
bool InitStack(LinkStack &S) //構造一個空棧S
{
S=NULL;
return true;
}
2. 入棧
入棧前要創建一個新結點,將元素e存入該結點的數值域:
p = new Snode; //生成新結點
p->data = e; //將e放在新結點數據域
然後將該結點的指針域指向S,再修改S指針指向該結點。
bool Push(LinkStack &S, int e) //在棧頂插入元素e
{
LinkStack p;
p = new Snode; //生成新結點
p->data = e; //將e放在新結點數據域
p->next = S; //將新結點的指針域指向S,即將S的地址賦值給新結點的指針域
S = p; //修改棧頂指針爲p
return true;
}
3. 出棧
出棧就是要把棧頂元素刪除,讓棧頂指針指向下一個結點,然後釋放該結點空間。因此先用指針p指向棧頂元素(S指針指向的結點),即p=S;然後棧頂指針S指向它的下一個結點,即S=S->next;最後釋放p指向的結點,即delete p。
bool Pop(LinkStack &S, int &e) //刪除S的棧頂元素,用e保存其值
{
LinkStack p;
if (S == NULL) //棧空
return false;
e = S->data; //將棧頂元素賦給e
p = S; //用p保存棧頂元素地址,以備釋放
S = S->next; //修改棧頂指針,指向下一個結點
delete p; //釋放原棧頂元素的空間
return true;
}
4. 取棧頂元素
取棧頂元素和出棧不同,取棧頂元素只是把棧頂元素複製一份,棧頂指針並沒有改變,而出棧是指刪除棧頂元素,棧頂指針指向了下一個元素。
int GetTop(LinkStack S) //返回S的棧頂元素,不修改棧頂指針
{
if (S != NULL) //棧非空
return S->data; //返回棧頂元素的值,棧頂指針不變
else
return -1;
}
鏈棧基本操作完整代碼:
完整代碼:
#include<iostream>
using namespace std;
typedef struct Snode {
int data; //數據域
struct Snode *next; //指針域
}Snode,*LinkStack;
bool InitStack(LinkStack &S) //構造一個空棧S
{
S=NULL;
return true;
}
bool Push(LinkStack &S, int e) //在棧頂插入元素e
{
LinkStack p;
p = new Snode; //生成新結點
p->data = e; //將e放在新結點數據域
p->next = S; //將新結點的指針域指向S,即將S的地址賦值給新結點的指針域
S = p; //修改棧頂指針爲p
return true;
}
bool Pop(LinkStack &S, int &e) //刪除S的棧頂元素,用e保存其值
{
LinkStack p;
if (S==NULL) //棧空
return false;
e=S->data; //將棧頂元素賦給e
p=S; //用p保存棧頂元素地址,以備釋放
S=S->next; //修改棧頂指針,指向下一個結點
delete p; //釋放原棧頂元素的空間
return true;
}
int GetTop(LinkStack S) //返回S的棧頂元素,不修改棧頂指針
{
if (S!=NULL) //棧非空
return S->data; //返回棧頂元素的值,棧頂指針不變
else
return -1;
}
int main()
{
int n,x;
LinkStack S;
InitStack(S);//初始化一個順序棧S
cout <<"請輸入元素個數n:" <<endl;
cin>>n;
cout <<"請依次輸入n個元素,依次入棧:" <<endl;
while(n--)
{
cin>>x; //輸入元素
Push(S, x);
}
cout <<"元素依次出棧:" <<endl;
while(S!=NULL)//如果棧不空,則依次出棧
{
cout<<GetTop(S)<<"\t";//輸出棧頂元素
Pop(S, x); //棧頂元素出棧
}
return 0;
}
運行結果: