數據結構筆記3.1.3
鏈式棧和前面的順序棧是棧的兩種不同實現形式,其實就是順序表與鏈式表,區別在於其實現的方式(數組和指針節點),順序棧指的是其每個節點的物理存儲是連續的,因爲是使用數組實現的。而鏈式棧存儲位置則是不連續的,需要指針來穿接。
但是因爲棧的操作單調,相對於單鏈表更容易實現,單鏈表相當於是一個泛泛的存儲表,其操作更加任意,而像棧、隊列這種數據組織結構,其只能在整個表的端進行操作,這也從另一個方面體現出鏈式棧相對容易實現。
那爲何有順序表這種總領性的結構,還要建立棧、隊列這些子數據結構呢?這就好比是“專門化”與“普遍化”的比較,一般專門化的東西,其在相應問題上的效率會比普遍使用的工具要高,所以,分化後的子結構其存在的意義絕不容小視!最後說一下順序棧與鏈式棧的比較,他們都是一種數據組織與操縱方式(DRO),但是在解決不同問題的時候,不同的存儲方式實現同樣的功能,可能在效率、複雜度、空間利用率等方面都會千差萬別,各有千秋!下面貼出代碼:
模板類——鏈式棧
//數據結構——鏈式棧的模板類定義 By Zhu Xiuyu 17/10/13
#include <iostream>
#include <cassert>
using namespace std;
//節點定義
template<class T>
struct StackNode {
T data; //棧每個節點的數據域
StackNode<T> *next; //棧節點的指針域
StackNode(T x, StackNode<T> *Node = NULL) : data(x){}
};
//模板類定義
template<class T>
class LinkedStack {
public:
LinkedStack() : top(NULL){} //構造函數
~LinkedStack(); //析構函數
void Push(const T & x); //進棧
bool Pop(T & x); //出棧
bool getTop(T & x) const; //讀取棧頂元素
bool isEmpty()const; //判斷棧是否爲NULL
int getSize() const; //求棧的元素的個數
void makeEmpty(); //清空棧
void output(ostream & out); //輸出函數(此處由重載函數調用)
private:
StackNode<T> *top; //棧頂指針
};
//函數定義
template<class T>
void LinkedStack<T>::makeEmpty() {
//逐個刪去鏈式棧中的元素,直至棧頂指針爲空
StackNode<T> *p; //逐個節點釋放
while (top != NULL) {
p = top;
top = top->next;
delete p;
}
}
template<class T>
LinkedStack<T>::~LinkedStack() {
//析構函數
makeEmpty();
}
template<class T>
bool LinkedStack<T>::isEmpty() const{
if (NULL == top) {
return true;
}
return false;
}
template<class T>
void LinkedStack<T>::Push(const T & x) {
//將元素x推入棧頂
StackNode<T> *newNode = new StackNode<T>(x);
assert(newNode != NULL); //內存分配錯誤的中斷處理
newNode->next = top;
top = newNode;
}
template<class T>
bool LinkedStack<T>::Pop(T & x) {
//刪除棧頂節點,刪除的data返回到x當中
if (isEmpty()) {
return false; //棧爲NULL出棧失敗
}
StackNode<T> *p = top; //標記Top
top = top->next; //更新棧頂指針
x = p->data;
delete p; //釋放棧頂元素
return true;
}
template<class T>
bool LinkedStack<T>::getTop(T & x) const {
//返回棧頂元素的值
if (isEmpty()) {
return false; //棧爲NULL,讀取棧頂失敗
}
x = top->data;
return true;
}
template<class T>
int LinkedStack<T>::getSize()const {
StackNode<T> *p = top;
int len = 0;
while (p != NULL) {
p = p->next;
len++;
}
return len;
}
template<class T>
void LinkedStack<T>::output(ostream & out) {
//輸出鏈式棧
StackNode<T> *p = top;
while (p != NULL) {
out << p->data << ' ';
p = p->next;
}
}
template<class T>
ostream & operator << (ostream & out, LinkedStack<T> & LS) {
//重載輸出運算符
LS.output(out); //避免友元函數在模板class中出現的問題
cout << endl;
return out;
}
測試Main函數
int main()
{
//Push and Pop測試
LinkedStack<int> LS; //定義一個鏈式棧
LS.Push(1);
LS.Push(2);
LS.Push(3);
LS.Push(4);
LS.Push(5);
cout << LS; //用重載函數輸出
int del1, del2;
LS.Pop(del1);
LS.Pop(del2);
cout << LS;
//getSize 和 getTop測試
int topVal = 0;
LS.getTop(topVal);
cout << topVal << endl;
cout << LS.getSize() << endl;
//判斷是否爲NULL測試
if (LS.isEmpty()) {
cout << "空棧" << endl;
}
else {
cout << "非空棧" << endl;
}
LS.makeEmpty();
if (LS.isEmpty()) {
cout << "空棧" << endl;
}
else {
cout << "非空棧" << endl;
}
system("pause");
return 0;
}
運行效果: