棧 Stack 的理解及其應用

2021-09-11 22:37:34 字數 3154 閱讀 9507

棧的抽象資料型別

棧的抽象資料型別由以下結構和操作定義:棧被構造為項的有序集合,其中項被新增和從末端移除的位置稱為「頂部」。棧是有序的 lifo 。棧操作如下:

簡單來說,類似於放一摞書,最先放的書在最下面,因此最後放的書最先取出來,而最後取出放的第一本書,棧就是這樣一種資料結構。我們可以用python的列表 (list) 定義乙個棧型別:

class

stack()

:def

__init__

(self)

: self.item =

defisempty

(self)

:return self.item ==

defpush

(self, item)

:def

pop(self)

:return self.item.pop(

)def

peek

(self)

:return self.item[-1

]def

size

(self)

:return

len(self.item)

簡單括號匹配

何為括號匹配?看簡單的幾個例子:

( ) ( ) ( ( (  ) ) ) ( ) # 該括號組合是匹配的

) ( ) ( ) # 該括號組合是不匹配的

區分括號是否匹配的能力是識別很多程式語言結構的重要部分。具有挑戰的是如何編寫乙個演算法,能夠從左到右讀取一串符號,並決定括號是否匹配。為了解決這個問題,我們需要做乙個重要的觀察。從左到右處理符號時,最近的左括號 (" ( 「) 必須與下乙個右括號 (」 ) ") 相匹配。此外,處理的第乙個左括號必須等待直到其匹配最後乙個右括號。右括號以相反的順序匹配左括號,他們從內到外匹配。這是乙個可以用棧解決問題的線索。

因此實現這個演算法的python**思路很清晰:

建立乙個空棧

讀取括號列表,第乙個括號若以左括號開始,將其壓入棧中,否則直接返回false(不匹配)

判斷下乙個括號型別,左括號繼續壓入棧中,若是右括號則刪除棧頂部左括號。

當列表遍歷完時,棧正好被清空,則括號匹配,返回true;其他情況返回false。

演算法實現的**如下:

def

parchecker

(symbolstring)

: s = stack(

)# 初始化定義的棧物件

balance =

true

# 初始化匹配狀態值

i =0while i <

len(symbolstring)

: symbol = symbolstring[i]

if symbol ==

'(':

s.push(symbol)

# 指標指到左括號便將其壓入棧

else

:if s.isempty():

# 指標指向右括號時棧為空,即沒有與之匹配的左括號,因此整體不匹配,返回false

balance ==

false

break

else

: s.pop(

)# 指標指向右括號時棧不為空,故刪除棧頂與之匹配的左括號

i +=

1# 指標右移乙個單位

return

true

if balance and s.isempty(

)else

false

拓展:上面顯示的匹配括號問題是許多程式語言都會出現的一般情況的特定情況。匹配和巢狀不同種類的開始和結束符號的情況經常發生。例如,在 python 中,方括號 [ ] 用於列表,花括號 用於字典。括號 ( ) 用於元祖和算術表示式。只要每個符號都能保持自己的開始和結束關係,就可以混合符號,甚至指定任意匹配方式的字串進行匹配。符號字串如

# 該符號組合是匹配的

( ) [ ]

( )

這些被恰當的匹配了,因為不僅每個開始符號都有對應的結束符號,而且符號的型別也匹配。相反這些字串沒法匹配:

# 該符號組合不是匹配的

( ) [ ] }

(

可以想到,處理多符號匹配的問題和簡單括號匹配的思路和演算法一樣,只不過需要記錄各符號各自的匹配關係。不難想到,在python中我們可以用字典 (dict) 的鍵值對儲存各個符號的匹配關係,以便呼叫。python實現**如下:

# 匹配 {}() 三種字元

defparchecker

(symbolstring)

: s = stack(

)# 初始化定義的棧物件

balance =

true

# 初始化匹配狀態值

dict_symbol =',

'[':

']',

'(':

')'}

i =0while i <

len(symbolstring)

: symbol = symbolstring[i]

if symbol in

'({['

: s.push(symbol)

# 指標指到左符號便將其壓入棧

else

:if s.isempty(

)or dict_symbol[s.peek()]

!= symbol:

# 指標指向右符號時棧為空,或是棧頂部符號與之不匹配,故整體不匹配,返回false

balance ==

false

break

else

: s.pop(

)# 指標指向右符號時棧頂部符號與之匹配,故刪除棧頂與之匹配的符號

i +=

1# 指標右移乙個單位

return

true

if balance and s.isempty(

)else

false

棧Stack的實現及其應用

棧 先進後出 實現方式有兩種,一種使用陣列,一種是鏈式結構 使用陣列的缺點就是在定義棧的時候就需要以某值初始化陣列,確定陣列的大小,也就是確定了棧的深度 棧 底層用陣列實現 public class arrstack 陣列滿的時候棧滿 public boolean isfull 棧空時top為 1 ...

棧(stack)的應用

棧 stack 通常也被稱之為 堆疊 它的本質是線性表。堆 heap 通常我們也稱它為優先佇列,本質是樹。此處講述一些stack的應用。編譯器在檢查 這樣成對出現的符號所造成的語法錯誤時,通常並不需要去設計乙個很複雜的程式去判斷。而是使用乙個簡單的演算法,這個演算法用到乙個棧。演算法描述如下 做乙個...

棧及其應用

棧又稱堆疊,是一種運算受限的線性表,其限制是僅允許在表的一端進行插入和刪除運算。把對棧進行運算的一端稱為棧頂,另一端稱為棧底。向乙個棧插入新元素稱為入棧或進棧,push 從乙個棧刪除元素稱為退棧或出棧,pop。因為後進棧的元素必定先出棧,所以又把棧稱為後進先出表 last in first out,...