C++數據結構之棧操作

一、綜述

   在我們學習的數據結構中,棧作爲一個相當常用的數據結構在各方面都有着相當大作用,而棧也因它的特殊的FILO(先進後出)的特性而被我們熟知。那我們今天就來看看棧的具體實現。
   關於棧我們可以選擇不同的邏輯結構來存放棧的數據——數組和鏈表。


   基於數組的棧的實現,我們在這裏就不在贅述,我們在這裏主要是面向鏈表這一邏輯結構完成棧“FILO”功能的實現。


   在此之前,我想我們應當明確,要完成棧這一數據結構,我們首先應當瞭解棧具有什麼特性,具有什麼樣的性質。瞭解這些之後,我們才能開始真正的完成棧的編碼工作:


   棧,本質上就是一種運算受限的線性表,因此我們主要考慮的就是他的特性,而對於棧,他的特性就是FILO。
   明白了這一點,我們便可以開始編碼——


   首先我們是基於鏈表來存放棧的數據,因此我們需要新建結點類,將棧的數據封裝進結點類,然後在根據棧的特性進行插入,刪除,遍歷等操作;
// 結點類
/*
@Author: Mica_Dai
@Date: sep 10th 2017 20:48:13
*/
class Node
{
public:
    Node(int x){
        data = x;
        next = nullptr;
    }

    ~Node(){
        delete next;
    }

    int getData(){
        return data;
    }

    Node* getNext(){
        return next;
    }

    void setNext(Node* node){
        next = node;
    }
private:
    int data;
    Node* next;
};


   然後我們在新建一個stack的類,因爲我們已經明確stack的操作主要是有以下的幾點:
  • 壓棧(push)
  • 出棧(pop)
  • 獲取棧頂元素(getTop)
  • 遍歷(traverse)

   因此建立以下的棧stack類:
// stack類
/*
@Author: Mica_Dai
@Date: sep 10th 2017 20:54:23
*/
class stack
{
public:
    stack(){
        top = nullptr;
    }
    ~stack();
    Node* push(int x);
    bool pop();
    Node* getTop();
    void traverse();
private:
    Node* top;
};






二、壓棧(push)

   可能有小夥伴兒要說了,你不是說要關注數據結構的特性嗎?怎麼不進入主題,反而其他的說那麼多?
   別急,我這就開始進入正題,對於棧的FILO特性,我們是通過插入操作也即壓棧操作實現的。
   那麼我們的壓棧究竟是怎樣完成的,才能實現棧的FILO特性呢?
   我們先看看壓棧的示意圖:
   壓棧也分爲兩種情況:



+ 其中之一是當棧爲空,沒有任何結點的時候,我們新建的node直接賦值給top就好;
+ 而對於棧的top部位空的時候,原理圖才如下:


push


   由以上的壓棧圖,我們不難分析出當我們壓棧的時候不就是我們在學鏈表插入時候的前插法創建鏈表麼!!
   而且這樣相當明確,當我們想要出棧的時候直接將top所指的結點刪除就完成了。同時這就是完成了棧的FILO!
   現在我們明白了原理,現在開始完成代碼:
// 前插法壓棧
Node* stack::push(int x){
    Node *node = new Node(x);
    cout << (top == nullptr) << endl;
    if (top == nullptr){
        top = node;
    }else{
        // Node *temp = top -> getnext;
        // top -> next = node;
        // node -> getNext() = top;
        node -> setNext(top);
        top = node;
    }   
    return top;
}






三、出棧(pop)

   出棧就是將棧頂元素刪除的操作,但是在執行之前需要檢查站是否爲空;代碼如下:
// 出棧函數
bool stack::pop(){
    if (top != nullptr)
    {
        /* code */
        top = top -> getNext();
        return true;
    }else{
        return false;
    }
}






四、獲取棧頂元素(getTop)

   這個也是當top不爲空的時候,直接將top返回就好;否則返回爲空。
Node* stack::getTop(){
    if (top != nullptr)
    {
        /* code */
        return top;
    }else{
        return nullptr;
    }
}






五、遍歷(traverse)

   遍歷時就是像前插法創建鏈表時候的特點,即遍歷出來的順序與插入的順序完全相反。也正是因爲這種情況才使得棧有這種FILO的特性。
   也是首先判斷top是否爲空——
// 遍歷函數
void stack::traverse(){
    Node *temp = top;
    while(temp != nullptr){
        cout << temp -> getData() << " ";
        temp = temp -> getNext();
        // cout << (top == nullptr) << endl;
    }
}


   在遍歷時候,同樣注意一個問題,不要直接使用top進行遍歷,否則遍歷一遍之後,top的值將會變爲nullptr,因此我們在遍歷時需要創建一個臨時變量,用臨時變量來遍歷。


   這便是棧的基本的操作。
   以上。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章