棧的應用

當某個數據集合只涉及在一端插入和刪除數據,並且滿足後進先出、先進後出的特性,我們就應該首選“棧”這種數據結構。

在函數調用中的應用

操作系統給每個線程分配了一塊獨立的內存空間,這塊內存被組織成“棧”這種結構, 用來存儲函數調用時的臨時變量。

每進入一個函數,就會將臨時變量作爲一個棧幀入棧,當被調用函數執行完成,返回之後,將這個函數對應的棧幀出棧。

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

爲什麼函數調用要用“棧”來保存臨時變量呢?用其他數據結構不行嗎?

不一定非要用棧來保存臨時變量,只不過如果這個函數調用符合後進先出的特性,用棧這種數據結構來實現,是最順理成章的選擇。

從調用函數進入被調用函數,對於數據來說,變化的是什麼呢?是作用域。所以根本上,只要能保證每進入一個新的函數,都是一個新的作用域就可以。而要實現這個,用棧就非常方便。在進入被調用函數的時候,分配一段棧空間給這個函數的變量,在函數結束的時候,將棧頂復位,正好回到調用函數的作用域內。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

在表達式求值中的應用

例如 34+13*9+44-12/3,

對於這個四則運算,我們人腦可以很快求解出答案,但是對於計算機來說,理解這個表達式本身就是個挺難的事。

實現這樣一個表達式求值,實際上編譯器就是通過兩個棧來實現的。

其中一個保存操作數的棧,另一個是保存運算符的棧。

從左到右遍歷表達式,當遇到操作數,就直接壓入操作數棧, 當遇到數字,我們就直接壓入操作數棧;

當遇到運算符,就與運算符棧的棧頂元素進行比較。

如果比運算符棧頂元素的優先級高,就將當前運算符壓入棧;

如果比運算符棧頂元素的優先級低或者相同,從運算符棧中取棧頂運算符,從操作數棧的棧頂取 2 個操作數,然後進行計算

再把計算完的結果壓入操作數棧,繼續比較。

例如,3+5*8-6

 

在括號匹配中的應用

假設表達式中只包含三種括號,圓括號 ()、方括號[]和花括號{},並且它們可以任意嵌套。

比如,{[] ()[{}]}或[{()}([])]等都爲合法格式,而{[}()]或[({)]爲不合法的格式。

如何檢查它是否合法,可以用棧來解決。我們用棧來保存未匹配的左括號,從左到右依次掃描字符串。

當掃描到左括號時,則將其壓入棧中;當掃描到右括號時,從棧頂取出一個左括號。

如果能夠匹配,則繼續掃描剩下的字符串。

如果掃描的過程中,遇到不能配對的右括號,或者棧中沒有數據,則說明爲非法格式。

當所有的括號都掃描完成之後,如果棧爲空,則說明字符串爲合法格式;

否則,說明有未匹配的左括號,爲非法格式。

 

棧的API

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