C語言實現順序棧以及棧的特點

什麼是棧?

順序表鏈表一樣,棧也是用來存儲邏輯關係爲 “一對一” 數據的線性存儲結構,如下圖所示。
圖一
從上圖我們看到,棧存儲結構與之前所學的線性存儲結構有所差異,這緣於棧對數據 “存” 和 “取” 的過程有特殊的要求:

  1. 棧只能從表的一端存取數據,另一端是封閉的,如上圖所示;
  2. 在棧中,無論是存數據還是取數據,都必須遵循"先進後出"的原則,即最先進棧的元素最後出棧。拿上圖的棧來說,從圖中數據的存儲狀態可判斷出,元素 1 是最先進的棧。因此,當需要從棧中取出元素 1 時,根據"先進後出"的原則,需提前將元素 3 和元素 2 從棧中取出,然後才能成功取出元素 1。

因此,我們可以給棧下一個定義,即棧是一種只能從表的一端存取數據且遵循 “先進後出” 原則的線性存儲結構

通常,棧的開口端被稱爲棧頂;相應地,封口端被稱爲棧底。因此,棧頂元素指的就是距離棧頂最近的元素,拿下圖來說,棧頂元素爲元素 4;同理,棧底元素指的是位於棧最底部的元素,下圖中的棧底元素爲元素。

1MHLQO.gif

進棧和出棧

基於棧結構的特點,在實際應用中,通常只會對棧執行以下兩種操作:

  • 向棧中添加元素,此過程被稱爲"進棧"(入棧壓棧);
  • 從棧中提取出指定元素,此過程被稱爲"出棧"(或彈棧);

棧的具體實現

棧是一種 “特殊” 的線性存儲結構,因此棧的具體實現有以下兩種方式:

  1. 順序棧:採用順序存儲結構可以模擬棧存儲數據的特點,從而實現棧存儲結構;
  2. 鏈棧:採用鏈式存儲結構實現棧結構;

兩種實現方式的區別,僅限於數據元素在實際物理空間上存放的相對位置,順序棧底層採用的是數組,鏈棧底層採用的是鏈表。有關順序棧和鏈棧的具體實現會在後續章節中作詳細講解。

順序棧基本操作

順序棧,即用順序表實現棧存儲結構。通過前面介紹我們知道,使用棧存儲結構操作數據元素必須遵守 “先進後出” 的原則,下面就 “如何使用順序表模擬棧以及實現對棧中數據的基本操作(出棧和入棧)” 給大家做一些介紹。

如果你仔細觀察順序表(底層實現是數組)和棧結構就會發現,它們存儲數據的方式高度相似,只不過棧對數據的存取過程有特殊的限制,而順序表沒有。

例如,我們先使用順序表(a 數組)存儲{1,2,3,4},存儲狀態如下圖所示:

在這裏插入圖片描述
同樣,使用棧存儲結構存儲{1,2,3,4},其存儲狀態如下圖所示:
在這裏插入圖片描述
通過上面兩張圖對比不難看出,使用順序表模擬棧結構很簡單,只需要將數據從 a 數組下標爲 0 的位置依次存儲即可。

從數組下標爲 0 的模擬棧存儲數據是常用的方法,從其他數組下標處存儲數據也完全可以,這裏只是爲了方便初學者理解。

瞭解了順序表模擬棧存儲數據後,接下來看如何模擬棧中元素出棧的操作。由於棧對存儲元素出棧的次序有"先進後出"的要求,如果想將圖中存儲的元素 1 從棧中取出,需先將元素 4、元素 3 和元素 2 依次從棧中取出。

這裏給出使用順序表模擬棧存儲結構常用的實現思路,即在順序表中設定一個實時指向棧頂元素的變量(一般命名爲 top),top 初始值爲 -1,表示棧中沒有存儲任何數據元素,及棧是"空棧"。一旦有數據元素進棧,則 top 就做 +1 操作;反之,如果數據元素出棧,top 就做 -1 操作。

順序棧元素"入棧"

比如,還是模擬棧存儲{1,2,3,4} 的過程。最初,棧是"空棧",即數組是空的,top 值爲初始值 -1,如下圖所示:
在這裏插入圖片描述
首先向棧中添加元素 1,我們默認數組下標爲 0 一端表示棧底,因此,元素 1 被存儲在數組 a[1] 處,同時 top 值 +1,如下圖所示:
在這裏插入圖片描述
採用以上的方式,依次存儲元素 2、3 和 4,最終,top 值變爲 3,如下圖所示:
在這裏插入圖片描述

因此,C 語言實現代碼爲:

//元素elem進棧,a爲數組,top值爲當前棧的棧頂位置
int push(int* a,int top,int elem){
    a[++top]=elem;
    return top;
}

代碼中的 a[++top]=elem,等價於先執行 ++top,再執行 a[top]=elem。

順序棧元素"出棧"

其實,top 變量的設置對模擬數據的 “入棧” 操作沒有實際的幫助,它是爲實現數據的 “出棧” 操作做準備的。

比如,將上圖中的元素 2 出棧,則需要先將元素 4 和元素 3 依次出棧。需要注意的是,當有數據出棧時,要將 top 做 -1 操作。因此,元素 4 和元素 3 出棧的過程分別如下圖a) 和 下圖b) 所示:
在這裏插入圖片描述

注意,上圖數組中元素的消失僅是爲了方便初學者學習,其實,這裏只需要對 top 值做 -1 操作即可,因爲 top 值本身就表示棧的棧頂位置,因此 top-1 就等同於棧頂元素出棧。並且後期向棧中添加元素時,新元素會存儲在類似元素 4 這樣的舊元素位置上,將舊元素覆蓋。

元素 4 和元素 3 全部出棧後,元素 2 才能出棧。因此,使用順序表模擬數據出棧操作的 C 語言實現代碼爲:

//數據元素出棧
int pop(int * a,int top){
    if (top==-1) {
        printf("空棧");
        return -1;
    }
    printf("彈棧元素:%d\n",a[top]);
    top--;
    return top;
}

代碼中的 if 語句是爲了防止用戶做 “棧中已無數據卻還要數據出棧” 的錯誤操作。代碼中,關於對棧中元素出棧操作的實現,只需要 top 值 -1 即可。

以上就是本次給大家分享的利用C語言簡單的實現順序棧以及向大家介紹了棧的特點,完整的代碼已經上傳到github,C語言實現順序棧 歡迎大家Star ! 想要了解其他相關數據結構算法實現的小夥伴也可以來我的博客MyBlog,我們一起交流,一起進步啊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章