数据结构与算法 / 栈(stack)
一、定義
? ? ? ? 棧是一個(gè)“操作受限”的線性表,只能在一端插入和刪除。
二、特性
? ? ? ? 先進(jìn)后出、后進(jìn)先出。
三、分類
四、應(yīng)用場(chǎng)景
1、棧在函數(shù)調(diào)用中的應(yīng)用(參考:《深入理解計(jì)算機(jī)系統(tǒng)》,機(jī)械工業(yè)出版社,第三版,3.7 節(jié))
棧在函數(shù)調(diào)用中被命名為調(diào)用棧(Call stack),調(diào)用棧由棧幀(Stack frame)組成。棧幀用于保存調(diào)用該函數(shù)的寄存器變量、本函數(shù)的局部變量、即將調(diào)用其他函數(shù)的參數(shù)的構(gòu)造區(qū)和被調(diào)用函數(shù)返回時(shí)本函數(shù)繼續(xù)執(zhí)行的地址(返回地址)。每個(gè)子函數(shù)如果想保存上述這些信息,都會(huì)在調(diào)用棧中申請(qǐng)一個(gè)棧幀。
不使用棧幀的函數(shù)也是有的,栗子:
void example() { }? ? ? ? (1)不需要改變調(diào)用該函數(shù)的寄存器的值。
? ? ? ? (2)沒(méi)有局部變量
? ? ? ? (3)沒(méi)有調(diào)用其他函數(shù),故沒(méi)有參數(shù)構(gòu)造區(qū)和返回地址。?
使用棧的原因是整個(gè)過(guò)程完美的符合棧的后進(jìn)先出的過(guò)程。
栗子:函數(shù) A 調(diào)用 B,B 調(diào)用 C。如果想都執(zhí)行完畢,返回 A 繼續(xù)執(zhí)行,那么需要釋放 C 的棧幀空間、之后再釋放 B 的棧幀空間、最后才能讓 A 繼續(xù)執(zhí)行。整個(gè)過(guò)程和棧的特性是一樣的。當(dāng)然了,用鏈表也是可以的,但是鏈表就會(huì)暴露太多的接口,給代碼查看人員很多疑惑,恰到好處最好!
2、棧在表達(dá)式求值中的應(yīng)用
表達(dá)式中從左到右,數(shù)字壓入棧,運(yùn)算符再壓入棧。每次壓入運(yùn)算符時(shí),比較當(dāng)前運(yùn)算符和棧頂運(yùn)算符哪個(gè)優(yōu)先級(jí)高,若當(dāng)前優(yōu)先級(jí)高,則運(yùn)算符繼續(xù)壓入,若棧頂運(yùn)算符優(yōu)先級(jí)高,則說(shuō)明棧頂?shù)倪\(yùn)算符可以進(jìn)行計(jì)算了。計(jì)算方法是從數(shù)字棧中取出兩個(gè)數(shù),和運(yùn)算符棧的棧頂元素進(jìn)行計(jì)算。以此類推,計(jì)算出整個(gè)表達(dá)式的值。
3、棧在括號(hào)匹配中的應(yīng)用
"(" 和 ")"匹配,"[" 和 "]"匹配,"{" 和 "}"匹配,但是三者兩兩混淆就有問(wèn)題了。
檢查的方法是每次從左到右依次將字符串中左(小、中、大)括號(hào)壓入棧中,當(dāng)首次掃描到右(小、中、大)括號(hào)時(shí),將該括號(hào)和棧頂元素進(jìn)行比較,若匹配則 pop 該棧頂元素,繼續(xù)掃描,若不匹配,則可以報(bào)括號(hào)不匹配的錯(cuò)誤。
五、實(shí)現(xiàn)(C++)
github?
?
(SAW:Game Over!)
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的数据结构与算法 / 栈(stack)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: gcc / -E、-S、-c 和 -o
- 下一篇: C/Cpp / extern 关键字