數據結構——鏈式棧模板類實現

數據結構筆記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;
}

運行效果:
這裏寫圖片描述  

發佈了50 篇原創文章 · 獲贊 228 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章