當(dāng)前位置:首頁 > 公眾號精選 > 小麥大叔
[導(dǎo)讀]棧(stack)是限定僅在表的一端進行操作的數(shù)據(jù)結(jié)構(gòu),且棧是一種先進后出的數(shù)據(jù)結(jié)構(gòu),允許操作的一端稱為棧頂,不允許操作的稱為棧底。




關(guān)注、星標公眾號 ,直達精彩內(nèi)容

ID:技術(shù)讓夢想更偉大

作者:李肖遙

棧的概念

棧(stack)是限定僅在表的一端進行操作的數(shù)據(jù)結(jié)構(gòu),且棧是一種先進后出的數(shù)據(jù)結(jié)構(gòu),允許操作的一端稱為棧頂,不允許操作的稱為棧底,如下圖所示:

之前我們講到了鏈表,我們只能夠?qū)ζ滏湵淼谋砦步Y(jié)點進行操作,并且只能進行插入一個新的結(jié)點與刪除最末尾的這個結(jié)點兩個操作,而這樣強限制性的‘鏈表’,就是我們所說的。

就像是一個死胡同一樣,只有一個出口,如圖所示,有個概念:

棧的結(jié)點設(shè)計

棧分為數(shù)組棧鏈表棧,其區(qū)別如下:

  • 數(shù)組棧使用數(shù)組進行功能的模擬,實現(xiàn)較為快速和便利;

  • 鏈表棧使用鏈表的思路去設(shè)計,實現(xiàn)相比較說較為麻煩,但是其穩(wěn)定,且不易出錯;

在鏈表棧中又分為靜態(tài)鏈表棧和動態(tài)鏈表棧,其區(qū)別如下:

  • 靜態(tài)鏈表棧給定棧的空間大小,不允許超過存儲超過給定數(shù)據(jù)大小的元素;

  • 動態(tài)棧使用的是自動創(chuàng)建空間的方法進行創(chuàng)建,只要符合機器的硬件要求以及編譯器的控制,其理論上是極大的。

數(shù)組棧

其實際就是用一段連續(xù)的存儲空間來存儲棧中的數(shù)據(jù)元素,有以下特點:

  1. 元素所占的存儲空間必須連續(xù),這里的連續(xù)是指的邏輯連續(xù),而不是物理連續(xù)。

  2. 元素在存儲空間的位置是按邏輯順序存放的

我們來舉例說明,鑒于C語言數(shù)組下標都是0開始,并且棧的使用需要的空間大小難以估計,所以初始化空棧的時候,不應(yīng)該設(shè)定棧的最大容量。

我們先為棧設(shè)定一個基本容量,在應(yīng)用過STACK_程當(dāng)中,當(dāng)棧的空間不夠用時,再逐漸擴大。

設(shè)定2個常量,STACK_INIT_SIZE(存儲空間初始化分配量)和STACK_INCREMENT(存儲空間分配增量),宏定義如下

#define?STACK_INIT_SIZE?1000?//數(shù)值可以根據(jù)實際情況確定
#define?STACK_INCREMENT?10???//數(shù)值可以根據(jù)實際情況確定

棧的定義如下

typedef?struct??????
{
????void?*base;?
????void?*top;
????int?stackSize;
}?SqSTACK;
  • base 表示棧底指針

  • top 表示棧頂指針

  • stackSize 表示棧當(dāng)前可以使用的最大容量

若base的值是NULL,表示棧結(jié)構(gòu)不存在;top初始值指向棧底,即top = base;

每當(dāng)插入新的元素時,指針top就增1,反之刪除就減1,非空棧中的棧頂指針始終在棧頂元素的下一個指針上面。

數(shù)據(jù)元素和棧頂指針的關(guān)系如下圖所示:

鏈表棧

我們以鏈表棧的動態(tài)鏈表棧為例子,進行棧的設(shè)計。

首先是棧的結(jié)點,設(shè)計出兩個結(jié)構(gòu)體,一個結(jié)構(gòu)體Node表示結(jié)點,其中包含有一個data域和next指針,如圖所示:

Node

其中data表示數(shù)據(jù),next指針表示下一個的指針,其指向下一個結(jié)點,通過next指針將各個結(jié)點鏈接。

接下來是我們設(shè)計的重點,為這個進行限制性的設(shè)計,我們需要額外添加一個結(jié)構(gòu)體,其包括了一個永遠指向棧頭的指針top一個計數(shù)器count記錄元素個數(shù)。

其主要功效就是設(shè)定允許操作元素的指針以及確定棧何時為空,如圖所示:

Stack

這里我采用的是top和count組合的方法。其代碼可以表示為:

//棧的結(jié)點設(shè)計
//單個結(jié)點設(shè)計,數(shù)據(jù)和下一個指針
typedef?struct?node?????
{

????int?data;?
????struct?node?*next;
}?Node;

利用上面的結(jié)點創(chuàng)建棧,分為指向頭結(jié)點的top指針和計數(shù)用的count

typedef?struct?stack????
{
????Node?*top;
????int?count;
}?Link_Stack;

棧的基本操作—入棧(壓棧)

入棧的基本順序可以用以下圖所示:

入棧(push)操作時,我們只需要找到top所指向的空間,創(chuàng)建一個新的結(jié)點,將新的結(jié)點的next指針指向top指針指向的空間,再將top指針轉(zhuǎn)移,并且指向新的結(jié)點,這就是是入棧操作。

其代碼可以表示為:


//入棧?push
Link_Stack?*Push_stack(Link_Stack?*p,?int?elem)
{
????if?(p?==?NULL)
????????return?NULL;
????Node?*temp;
????temp=(Node*)malloc(sizeof(Node));
????//temp?=?new?Node;
????temp->data?=?elem;
????temp->next?=?p->top;
????p->top?=?temp;
????p->count++;
????return?p;
}

棧的基本操作—出棧

出棧(pop)操作,是在棧不為空的情況下,重復(fù)說一次,一定要進行判空操作,將棧頂?shù)脑貏h除,同時top指針,next向下進行移動即可的操作。

其代碼可以表示為:

//出棧?pop
Link_Stack?*Pop_stack(Link_Stack?*p)
{
????Node?*temp;
????temp?=?p->top;
????if?(p->top?==?NULL)
????{
????????printf("錯誤:棧為空");
????????return?p;
????}
????else
????{
????????p->top?=?p->top->next;
????????free(temp);
????????//delete?temp;
????????p->count--;
????????return?p;
????}
}

棧的基本操作—遍歷

這個就很常見了,也是我們調(diào)試必須的手段。

棧的遍歷相對而言比較復(fù)雜,由于棧的特殊性質(zhì),其只允許在一端進行操作,所以遍歷操作操作永遠都是逆序的。

簡單一點描述,其過程為,在棧不為空的情況下,一次從棧頂元素向下訪問,直到指針指向空(即到棧尾)為結(jié)束。

其代碼可以表示為:

//遍歷棧:輸出棧中所有元素
int?show_stack(Link_Stack?*p)
{
????Node?*temp;
????temp?=?p->top;
????if?(p->top?==?NULL)
????{
????????printf("");
????????printf("錯誤:棧為空");
????????return?0;
????}
????while?(temp?!=?NULL)
????{
????????printf("%d\t",?temp->data);
????????temp?=?temp->next;
????}
????printf("\n");
????return?0;
}

棧數(shù)組與棧鏈表的代碼實現(xiàn)

最后呢,我們使用代碼來幫助我們了解一下:

棧數(shù)組

數(shù)組棧是一種更為快速的模擬實現(xiàn)棧的方法,這里我們不多說。

模擬,就是不采用真實的鏈表設(shè)計,轉(zhuǎn)而采用數(shù)組的方式進行模擬操作。

也就是說這是一種仿真類型的操作,其可以快速的幫助我們構(gòu)建代碼,分析過程,相應(yīng)的實現(xiàn)起來也更加的便捷。

其代碼如下:

#include
#include
#include
#define?maxn?10000
?
//結(jié)點設(shè)計
typedef?struct?stack{
????int?data[maxn];
????int?top;
}stack;
?
//創(chuàng)建
stack?*init(){
????stack?*s=(stack?*)malloc(sizeof(stack));
????if(s==NULL){
????????printf("分配內(nèi)存空間失敗");
????????exit(0);
????}
????memset(s->data,0,sizeof(s->data));
????//memset操作來自于庫文件string.h,其表示將整個空間進行初始化
????//不理解可以查閱百度百科https://baike.baidu.com/item/memset/4747579?fr=aladdin
????s->top=0;?????//棧的top和bottom均為0(表示為空)
????return?s;
}
?
//入棧push
void?push(stack?*s,int?data){
????s->data[s->top]=data;
????s->top++;
}
?
//出棧pop
void?pop(stack?*s){
????if(s->top!=0){
????????s->data[s->top]=0;??//讓其回歸0模擬表示未初始化即可
????????s->top--;
????}
}
?
//模擬打印棧中元素
void?print_stack(stack?*s){
????for(int?n=s->top-1;n>=0;n--){
????????printf("%d\t",s->data[n]);
????}
????printf("\n");???//習(xí)慣性換行
}
?
int?main(){
????stack?*s=init();
????int?input[5]={11,22,33,44,55};??//模擬五個輸入數(shù)據(jù)
????for(int?i=0;i<5;i++){
????????push(s,input[i]);
????}
????print_stack(s);
????/////////////
????pop(s);
????print_stack(s);
????return?0;
}

其編譯結(jié)果如下:

棧鏈表

#include?
#include?
//棧的結(jié)點設(shè)計
//單個結(jié)點設(shè)計,數(shù)據(jù)和下一個指針
typedef?struct?node?????
{

????int?data;?
????struct?node?*next;
}?Node;
//利用上面的結(jié)點創(chuàng)建棧,分為指向頭結(jié)點的top指針和計數(shù)用的count
typedef?struct?stack????
{

????Node?*top;
????int?count;
}?Link_Stack;
?
//創(chuàng)建棧
Link_Stack?*Creat_stack()
{
????Link_Stack?*p;
????//p?=?new?Link_Stack;
????p=(Link_Stack*)malloc(sizeof(Link_Stack));
????if(p==NULL){
????????printf("創(chuàng)建失敗,即將退出程序");
????????exit(0);
????}
?else
?{printf("創(chuàng)建成功\n");
?}
????p->count?=?0;
????p->top?=?NULL;
????return?p;
}
?
//入棧?push
Link_Stack?*Push_stack(Link_Stack?*p,?int?elem)
{
????if?(p?==?NULL)
????????return?NULL;
????Node?*temp;
????temp=(Node*)malloc(sizeof(Node));
????//temp?=?new?Node;
????temp->data?=?elem;
????temp->next?=?p->top;
????p->top?=?temp;
????p->count++;
????return?p;
}
?
//出棧?pop
Link_Stack?*Pop_stack(Link_Stack?*p)
{
????Node?*temp;
????temp?=?p->top;
????if?(p->top?==?NULL)
????{
????????printf("錯誤:棧為空");
????????return?p;
????}
????else
????{
???printf("\npop?success");
????????p->top?=?p->top->next;
????????free(temp);
????????//delete?temp;
????????p->count--;
????????return?p;
????}
}
?
//遍歷棧:輸出棧中所有元素
int?show_stack(Link_Stack?*p)
{
????Node?*temp;
????temp?=?p->top;
????if?(p->top?==?NULL)
????{
????????printf("");
????????printf("錯誤:棧為空");
????????return?0;
????}
????while?(temp?!=?NULL)
????{
????????printf("%d\t",?temp->data);
????????temp?=?temp->next;
????}
????printf("\n");
????return?0;
}
?
int?main()
{?//用主函數(shù)測試一下功能
?int?i;
????Link_Stack?*p;
????p?=?Creat_stack();
????int?n?=?5;
????int?input[6]?=?{10,20,30,40,50,60};
????/////////////以依次入棧的方式創(chuàng)建整個棧//////////////
????for(i=0;i????????Push_stack(p,?input[i]);
????}
????show_stack(p);
????////////////////////出棧///////////////////////
????Pop_stack(p);
????show_stack(p);
????return?0;
}

編譯結(jié)果如下:

關(guān)于棧的總結(jié)

棧-它是一種運算受限的線性表,在數(shù)制轉(zhuǎn)換,括號匹配的檢驗,表達式求值等方面都可以使用,并且較為簡便的解決問題。

今天?;A(chǔ)就講到這里,下一期,我們再見!


推薦閱讀:


    
             
嵌入式編程專輯
Linux 學(xué)習(xí)專輯
C/C++編程專輯

關(guān)注 微信公眾號『技術(shù)讓夢想更偉大』,后臺回復(fù)“ m ”查看更多內(nèi)容,回復(fù)“ 加群 ”加入技術(shù)交流群。

長按前往圖中包含的公眾號關(guān)注

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉