Python演算法實戰系列之棧

發表於2017-04-04

棧(stack)又稱之為堆疊是一個特殊的有序表,其插入和刪除操作都在棧頂進行操作,並且按照先進後出,後進先出的規則進行運作。


如下圖所示

Python演算法實戰系列之棧

例如槍的彈匣,第一顆放進彈匣的子彈反而在發射出去的時候是最後一個,而最後放入彈匣的一顆子彈在打出去的時候是第一顆發射出去的。

棧的介面

如果你建立了一個棧,那麼那麼應該具有以下介面來進行對棧的操作

介面 描述
push() 入棧
pop() 出棧
isEmpty() 判斷是否為空棧
length() 獲取棧的長度
getTop() 取棧頂的元素,元素不出棧

知道棧需要上述的介面後,那麼在Python中,列表就類似是一個棧,提供介面如下:

操作 描述
s = [] 建立一個棧
s.append(x) 往棧內新增一個元素
s.pop() 在棧內刪除一個元素
not s 判斷是否為空棧
len(s) 獲取棧內元素的數量
s[-1] 獲取棧頂的元素

Python中的棧介面使用例項:

一大波例項

在瞭解棧的基本概念之後,讓我們再來看幾個例項,以便於理解棧。

括號匹配

題目

假如表示式中允許包含三中括號()[]{},其巢狀順序是任意的,例如:

正確的格式

錯誤的格式

編寫一個函式,判斷一個表示式字串,括號匹配是否正確

思路

  1. 建立一個空棧,用來儲存尚未找到的左括號;
  2. 便利字串,遇到左括號則壓棧,遇到右括號則出棧一個左括號進行匹配;
  3. 在第二步驟過程中,如果空棧情況下遇到右括號,說明缺少左括號,不匹配;
  4. 在第二步驟遍歷結束時,棧不為空,說明缺少右括號,不匹配;

解決程式碼

建議在pycharm中打斷點,以便於更好的理解

迷宮問題

題目

用一個二維陣列表示一個簡單的迷宮,用0表示通路,用1表示阻斷,老鼠在每個點上可以移動相鄰的東南西北四個點,設計一個演算法,模擬老鼠走迷宮,找到從入口到出口的一條路徑。

如圖所示

Python演算法實戰系列之棧

出去的正確線路如圖中的紅線所示

思路

  1. 用一個棧來記錄老鼠從入口到出口的路徑
  2. 走到某點後,將該點左邊壓棧,並把該點值置為1,表示走過了;
  3. 從臨近的四個點中可到達的點中任意選取一個,走到該點;
  4. 如果在到達某點後臨近的4個點都不走,說明已經走入死衚衕,此時退棧,退回一步嘗試其他點;
  5. 反覆執行第二、三、四步驟直到找到出口;

解決程式碼

字尾表示式求值

題目

計算一個表示式時,編譯器通常使用字尾表示式,這種表示式不需要括號:

中綴表示式 字尾表示式
2 + 3 * 4 2 3 4 * +
( 1 + 2 ) * ( 6 / 3 ) + 2 1 2 + 6 3 / * 2 +
18 / ( 3 * ( 1 + 2 ) ) 18 3 1 2 + * /

編寫程式實現字尾表示式求值函式。

思路

  1. 建立一個棧來儲存待計算的運算元;
  2. 遍歷字串,遇到運算元則壓入棧中,遇到操作符號則出棧運算元(n次),進行相應的計算,計算結果是新的運算元壓回棧中,等待計算
  3. 按上述過程,遍歷完整個表示式,棧中只剩下最終結果;

解決程式碼

揹包問題

題目

有一個揹包能裝10kg的物品,現在有6件物品分別為:

物品名稱 重量
物品0 1kg
物品1 8kg
物品2 4kg
物品3 3kg
物品4 5kg
物品5 2kg

編寫找出所有能將揹包裝滿的解,如物品1+物品5。

解決程式碼

相關文章