理论基础 —— 栈
【概述】
棧(Stack)是一種特殊的線性表,只能在某一端插入和刪除的特殊線性表。它按照后進(jìn)先出的原則存儲(chǔ)數(shù)據(jù),先進(jìn)入的數(shù)據(jù)被壓入棧底,最后的數(shù)據(jù)在棧頂。
由于棧滿足先進(jìn)后出,后進(jìn)先出的性質(zhì),因此也被稱為先進(jìn)后出表(FILO)或后進(jìn)先出表(LIFO)
當(dāng)棧中元素個(gè)數(shù)為零時(shí)稱為空棧。
【棧的邏輯結(jié)構(gòu)】
棧的棧底固定,棧頂浮動(dòng),允許進(jìn)行插入和刪除操作的一端稱為棧頂(Top),另一端為棧底(Bottom),插入一個(gè)元素稱為進(jìn)棧(Push),刪除一個(gè)棧頂元素稱為出棧(Pop)。
無論是順序棧還是鏈棧,其出棧、入棧的時(shí)間復(fù)雜度均為 O(1)
當(dāng)棧滿時(shí)再插入元素,將發(fā)生上溢,當(dāng)棧為空時(shí)刪除元素,將發(fā)生下溢。
【棧的順序存儲(chǔ)結(jié)構(gòu)】
1.順序棧
棧的順序存儲(chǔ)結(jié)構(gòu)即順序棧,其使用數(shù)組來模擬棧,并設(shè)置一個(gè)棧頂指針 top,選用 a[0] 作為棧底,a[top] 作為棧頂
其元素個(gè)數(shù)存在限制,并且可能造成空間浪費(fèi)。
2.雙端棧
在一個(gè)程序中有時(shí)需要同時(shí)使用具有相同數(shù)據(jù)類型的兩個(gè)棧,當(dāng)為他們開辟相同的存儲(chǔ)空間后,某一時(shí)刻一個(gè)棧已經(jīng)滿了,而另一個(gè)棧還有很大的空間,這樣會(huì)造成存儲(chǔ)空間的浪費(fèi),此時(shí)可以令兩棧共享空間,即使用雙端棧。
使用一個(gè)數(shù)組來存儲(chǔ)兩個(gè)棧,讓一個(gè)棧的棧底為該數(shù)組的始端(a[0]),另一個(gè)棧的棧底為該數(shù)組的末端(a[n-1]),兩個(gè)棧從各自的端點(diǎn)向中間延伸(top1++,top2--)。
由于雙端棧的特性,因此其一般是用于具有兩棧空間需求存在相反情況時(shí),即一個(gè)棧增長(zhǎng),另一個(gè)棧縮短的情況。
【棧的邏輯存儲(chǔ)結(jié)構(gòu)】
棧的邏輯存儲(chǔ)結(jié)構(gòu)即鏈棧,其將鏈表的頭指針作為棧頂,便于插入、刪除操作。
由于其空間是動(dòng)態(tài)擴(kuò)展的,因此一般不存在上溢的問題,只有當(dāng)內(nèi)存沒有可用空間時(shí)才會(huì)出現(xiàn)棧滿,但每個(gè)元素都需要一個(gè)指針域,從而產(chǎn)生了結(jié)構(gòu)性開銷。
【實(shí)現(xiàn)】
【應(yīng)用】
1.中綴表達(dá)式
中綴表達(dá)式:運(yùn)算符在兩個(gè)運(yùn)算對(duì)象中間,基本運(yùn)算符有 +、-、*、/、()、# 等,其中 # 為中綴表達(dá)式的界定符
例如:#3*(4+2)/2-5# 就是一個(gè)中綴表達(dá)式
在進(jìn)行運(yùn)算時(shí),要考慮運(yùn)算符的優(yōu)先級(jí)與結(jié)合性,常見運(yùn)算符優(yōu)先級(jí)表如下:
中綴表達(dá)式的求值過程用到兩個(gè)棧:運(yùn)算對(duì)象棧 Opnd、運(yùn)算符棧 Optr,算法偽代碼如下:
1)若當(dāng)前字符是操作數(shù):入棧 Opnd
2)若當(dāng)前字符是運(yùn)算符
? ①當(dāng)前運(yùn)算符優(yōu)先級(jí) > 棧 Optr 的棧頂運(yùn)算符優(yōu)先級(jí):入棧 Optr,處理下一字符
? ②當(dāng)前運(yùn)算符優(yōu)先級(jí) <?棧 Optr 的棧頂運(yùn)算符優(yōu)先級(jí):棧 Opnd 出棧兩個(gè)操作數(shù),棧 Optr 出棧一個(gè)運(yùn)算符,進(jìn)行運(yùn)算后將結(jié)果入棧 Opnd,處理當(dāng)前字符
? ③當(dāng)前運(yùn)算符優(yōu)先級(jí) = 棧 Optr 的棧頂運(yùn)算符優(yōu)先級(jí):棧 Optr 棧頂元素出棧,處理下一字符
以下圖為例:
2.中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式
后綴表達(dá)式:所有的計(jì)算按照運(yùn)算符出現(xiàn)的順序從左向右進(jìn)行,不用考慮運(yùn)算符的優(yōu)先級(jí)
例如:中綴表達(dá)式 3*(4+2)/2-5 對(duì)應(yīng)后綴表達(dá)式 3 4 2 + * 2 / 5 -
為了處理方便,常將中綴表達(dá)式轉(zhuǎn)為等價(jià)的后綴表達(dá)式,在轉(zhuǎn)換過程中用到一個(gè)棧 S,算法偽代碼如下:
1)若當(dāng)前字符是操作數(shù):輸出該字符,處理下一字符
2)若當(dāng)前字符是運(yùn)算符:
? ①當(dāng)前運(yùn)算符優(yōu)先級(jí) > 棧?S 棧頂運(yùn)算符優(yōu)先級(jí):該運(yùn)算符入棧 S,處理下一字符
? ②當(dāng)前運(yùn)算符優(yōu)先級(jí) <?棧?S 棧頂運(yùn)算符優(yōu)先級(jí):棧 S 棧頂運(yùn)算符彈出并輸出,處理當(dāng)前字符
? ③當(dāng)前運(yùn)算符優(yōu)先級(jí) =?棧?S 棧頂運(yùn)算符優(yōu)先級(jí):棧 S 棧頂運(yùn)算符彈出,處理向下一字符
3.后綴表達(dá)式求值
后綴表達(dá)式的求值過程中用到一個(gè)棧 S,算法偽代碼如下:
1)若當(dāng)前字符是操作數(shù):入棧 S,處理下一個(gè)字符
2)若當(dāng)前字符是運(yùn)算符:棧 S 出棧兩個(gè)操作數(shù),進(jìn)行運(yùn)算并將執(zhí)行結(jié)果入棧 S,處理下一個(gè)字符
以下圖為例:
?
?
總結(jié)
- 上一篇: 信息学奥赛一本通(1055:判断闰年)
- 下一篇: 数列分块入门 3(LibreOj-627