一,鏈棧的形式
鏈棧是指採用鏈式存儲結構實現的棧。
通常用單鏈表來表示,鏈棧的結點結構與單鏈表的結構相同。
二,鏈棧的結構體表示
struct Node
{
Node *next; //下一結點
int data; //當前結點的數據域
};
圖解:
類比單鏈表可以得出兩個性質
- 鏈棧無上限,只要需要入棧,都可添加進去
- 鏈棧判斷空的方法就是P是否等於NULL
當結構體作爲形參時,應該如何定義函數
這個地方令我突然不會寫單鏈表了。
- 首先看一種函數定義 void Init(Node *P); 可以看出如果這樣傳入實參P結點,則對於形參的賦值等一系列活動只在Init函數裏面有用,主函數裏面的實參並未發生變化。
- 再看第二種,void Init(Node &P);,此時若形參發生變化,則主函數裏面的實參也就會發生變化。但是此時有另一個問題。在函數Init裏面如何定義一個Node &類型的數據,與實參進行數據對接(這個方式我還沒想明白,如果誰會可以留言或私信,進行討論)
- 通過查資料,最後找到第三種方式,Node *Init(Node *P).此處將雖然形參依舊不影響實參,但是可以形參改變後通過返回,再與主函數中的實參對接。
(有什麼更好的方法歡迎留言或私信討論)
鏈棧的定義
Node *Init()
{
Node *A = new Node;
A = NULL; //將A賦值爲空
return A;
}
新定義一個A,然後將A賦值爲NULL,作爲棧底,然後返回。
入棧
Node *Push(Node *P)
{
Node *A = new Node; //定義新節點
cout << "入棧值爲:";
cin>>A->data;
A->next = P; //將A插入
P = A;
return P; //返回以P爲頭的鏈棧
}
先將實參傳遞進函數,經過賦值之後再返回。
出棧
Node *Pop(Node *P)
{
P = P->next; //P指向P的下一位
return P;
}
出棧後,P指向下一位(如需獲得出棧前棧頂,可自行添加代碼)
顯示棧頂元素
void ShowTop(Node *P)
{
if (P != NULL) //判斷棧是否爲空
{
cout << "棧頂元素爲:" << P->data << endl;
}
else
{
cout << "棧爲空";
}
}
因爲P指向的就是棧頂元素,所以當P不爲空時,直接顯示P->data就可以
遍歷鏈棧
void ShowAll(Node *P)
{
if (P == NULL) //若不爲空則繼續
{
return;
}
else
{
cout << P->data; //顯示當前棧頂元素
ShowAll(P->next); //將棧頂下一元素繼續做形參遞歸
}
}
此處棧的遍歷用的遞歸的方法:即每次顯示棧頂元素,然後再將棧頂下一位作爲形參繼續遍歷,知道棧爲空
三,代碼
#include<iostream>
using namespace std;
struct Node
{
Node *next;
int data;
};
Node *Init()
{
Node *A = new Node;
A = NULL;
return A;
}
Node *Push(Node *P)
{
Node *A = new Node;
cout << "入棧值爲:";
cin>>A->data;
A->next = P;
P = A;
return P;
}
Node *Pop(Node *P)
{
P = P->next;
return P;
}
void ShowTop(Node *P)
{
if (P != NULL)
{
cout << "棧頂元素爲:" << P->data << endl;
}
else
{
cout << "棧爲空";
}
}
void ShowAll(Node *P)
{
if (P == NULL)
{
return;
}
else
{
cout << P->data;
ShowAll(P->next);
}
}
int main()
{
Node *P = Init();
P = Push(P);
ShowTop(P);
P = Push(P);
ShowTop(P);
P = Pop(P);
ShowTop(P);
P = Push(P);
P = Push(P);
ShowAll(P);
system("pause");
}