數(shù)據(jù)結(jié)構(gòu)與算法-棧

問題引入

當(dāng)在瀏覽器頁面打開頁面 a-b-c 之后,點擊瀏覽器的后退按鈕漂佩,就可以查看之前瀏覽過的頁面 b 和 a久信。當(dāng)你后退到頁面 a,點擊前進(jìn)按鈕蝴猪,就可以重新查看頁面 b 和 c调衰。但是,如果你后退到頁面 b 后自阱,點擊了新的頁面 d嚎莉,那就無法再通過前進(jìn)、后退功能查看頁面 c 了沛豌。

當(dāng)某個數(shù)據(jù)集合只涉及在一端插入和刪除數(shù)據(jù)趋箩,并且滿足后進(jìn)先出、先進(jìn)后出的特性加派,我們就應(yīng)該首選“椊腥罚”這種數(shù)據(jù)結(jié)構(gòu)。
以上的場景就可以用\color{#FF0000}{棧}這種數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)芍锦。

代碼實現(xiàn)

棧主要包含兩個操作竹勉,入棧和出棧,也就是在棧頂插入一個數(shù)據(jù)和從棧頂刪除一個數(shù)據(jù)醉旦。
棧既可以用數(shù)組來實現(xiàn)饶米,也可以用鏈表來實現(xiàn)。用數(shù)組實現(xiàn)的棧车胡,我們叫作順序棧檬输,用鏈表實現(xiàn)的棧,我們叫作鏈?zhǔn)綏?/strong>匈棘。

進(jìn)棧與出棧

1. 順序棧

typedef int Status;
typedef int SElemType; /* SElemType類型根據(jù)實際情況而定丧慈,這里假設(shè)為int */

/* 順序棧結(jié)構(gòu) */
typedef struct
{
    SElemType data[MAXSIZE];
    int top; /* 用于棧頂指針 */
}SqStack;
/*  構(gòu)造一個空棧S */
Status InitStack(SqStack *S)
{
    /* S.data=(SElemType *)malloc(MAXSIZE*sizeof(SElemType)); */
    S->top=-1;
    return OK;
}
/* 插入元素e為新的棧頂元素 */
Status Push(SqStack *S,SElemType e)
{
    if(S->top == MAXSIZE -1) /* 棧滿 */
    {
        return ERROR;
    }
    S->top++;                /* 棧頂指針增加一 */
    S->data[S->top]=e;  /* 將新插入元素賦值給棧頂空間 */
    return OK;
}

/* 若棧不空,則刪除S的棧頂元素,用e返回其值逃默,并返回OK鹃愤;否則返回ERROR */
Status Pop(SqStack *S,SElemType *e)
{
    if(S->top==-1)
        return ERROR;
    *e=S->data[S->top];    /* 將要刪除的棧頂元素賦值給e */
    S->top--;                /* 棧頂指針減一 */
    return OK;
}

2. 鏈?zhǔn)綏?/h3>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存儲空間初始分配量 */
typedef int Status;
typedef int SElemType; /* SElemType類型根據(jù)實際情況而定,這里假設(shè)為int */

/* 鏈棧結(jié)構(gòu) */
typedef struct StackNode
{
   SElemType data;
   struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct
{
   LinkStackPtr top;
   int count;
}LinkStack;

/*  構(gòu)造一個空棧S */
Status InitStack(LinkStack *S)
{
   S->top = (LinkStackPtr)malloc(sizeof(StackNode));
   if(!S->top)
       return ERROR;
   S->top=NULL;
   S->count=0;
   return OK;
}

/* 插入元素e為新的棧頂元素 */
Status Push(LinkStack *S,SElemType e)
{
   LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));
   s->data=e;
   s->next=S->top;    /* 把當(dāng)前的棧頂元素賦值給新結(jié)點的直接后繼完域,見圖中① */
   S->top=s;         /* 將新的結(jié)點s賦值給棧頂指針软吐,見圖中② */
   S->count++;
   return OK;
}

/* 若棧不空,則刪除S的棧頂元素吟税,用e返回其值凹耙,并返回OK;否則返回ERROR */
Status Pop(LinkStack *S,SElemType *e)
{
   LinkStackPtr p;
   if(StackEmpty(*S))
       return ERROR;
   *e=S->top->data;
   p=S->top;                    /* 將棧頂結(jié)點賦值給p肠仪,見圖中③ */
   S->top=S->top->next;    /* 使得棧頂指針下移一位肖抱,指向后一結(jié)點,見圖中④ */
   free(p);                    /* 釋放結(jié)點p */
   S->count--;
   return OK;
}

空間復(fù)雜度:
不管是順序棧還是鏈?zhǔn)綏R炀桑覀兇鎯?shù)據(jù)只需要一個大小為 n 的數(shù)組就夠了意述。在入棧和出棧過程中,只需要一兩個臨時變量存儲空間吮蛹,所以空間復(fù)雜度[1]是 O(1)荤崇。
時間復(fù)雜度:
時間復(fù)雜度也同樣,不管是順序棧還是鏈?zhǔn)綏Fヤ蹋霔L焓浴⒊鰲V簧婕皸m攤€別數(shù)據(jù)的操作槐壳,所以時間復(fù)雜度都是 O(1)然低。

[1]:這里存儲數(shù)據(jù)需要一個大小為 n 的數(shù)組,并不是說空間復(fù)雜度就是 O(n)务唐。因為雳攘,這 n 個空間是必須的,無法省掉枫笛。所以我們說空間復(fù)雜度的時候吨灭,是指除了原本的數(shù)據(jù)存儲空間外,算法運行還需要額外的存儲空間刑巧。

應(yīng)用場景

  • 函數(shù)調(diào)用棧
  • 表達(dá)式求知
  • 括號匹配

源碼

本文完整源碼地址

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喧兄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子啊楚,更是在濱河造成了極大的恐慌吠冤,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恭理,死亡現(xiàn)場離奇詭異拯辙,居然都是意外死亡,警方通過查閱死者的電腦和手機颜价,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門涯保,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诉濒,“玉大人,你說我怎么就攤上這事夕春∥椿模” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵及志,是天一觀的道長茄猫。 經(jīng)常有香客問我,道長困肩,這世上最難降的妖魔是什么划纽? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮锌畸,結(jié)果婚禮上勇劣,老公的妹妹穿的比我還像新娘。我一直安慰自己潭枣,他們只是感情好比默,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盆犁,像睡著了一般命咐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谐岁,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天醋奠,我揣著相機與錄音,去河邊找鬼伊佃。 笑死窜司,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的航揉。 我是一名探鬼主播塞祈,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼帅涂!你這毒婦竟也來了议薪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤媳友,失蹤者是張志新(化名)和其女友劉穎斯议,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庆锦,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡捅位,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艇搀。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡尿扯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出焰雕,到底是詐尸還是另有隱情衷笋,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布矩屁,位于F島的核電站辟宗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吝秕。R本人自食惡果不足惜泊脐,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烁峭。 院中可真熱鬧容客,春花似錦、人聲如沸约郁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鬓梅。三九已至供置,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绽快,已是汗流浹背芥丧。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谎僻,地道東北人娄柳。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像艘绍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秫筏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 棧:如何實現(xiàn)瀏覽器的前進(jìn)和后退功能这敬? 瀏覽器的前進(jìn)航夺、后退功能,我想你肯定很熟悉吧崔涂? 當(dāng)你依次訪問完一串頁面 a-b...
    GhostintheCode閱讀 903評論 0 2
  • 棧 同順序表和鏈表一樣阳掐,棧也是用來存儲邏輯關(guān)系為 "一對一" 數(shù)據(jù)的線性存儲結(jié)構(gòu),如圖1 所示: 棧對數(shù)據(jù) "存"...
    hadoop_a9bb閱讀 1,290評論 0 0
  • 一汛闸、棧 1.1 棧的實現(xiàn) 棧(Stack)是限制僅在表的一端進(jìn)行插入和刪除運算的線性表。java沒有棧這樣的數(shù)據(jù)結(jié)...
    yjaal閱讀 1,451評論 0 1
  • 棧和隊列 棧 棧(Stack)是限制在表的一端進(jìn)行插入和刪除運算的線性表艺骂,通常稱插入诸老、刪除的這一端為棧頂(Top)...
    北風(fēng)知我意閱讀 318評論 0 0
  • 棧 棧的英文單詞是Stack,它代表一種特殊的線性表,這種線性表只能在固定一端(通常認(rèn)為是線性表的尾端)進(jìn)行插入钳恕,...
    Jack921閱讀 1,501評論 0 5