堆棧:先入後出,只能在一端進行操作
隊列:先入先出,一端進入,一端出列
※ 堆棧和隊列的適用場景
堆棧:
- 用於符號的匹配:在編譯器的語法檢查中,一個過程就是檢查各種括號是否匹配,比如 ([]) ,這就是匹配的,而 {[}] 就不匹配了。
- 用於計算代數式:如果我們要計算 6 + 4 * 8 ,要考慮到優先級的問題;先要把代數式構造成 6 4 8 * + 的形式;逐個讀取數據,當讀到數字時,把數字入棧;讀到運算符時,彈出棧中的兩個元素進行運算並把結果壓入棧中;
- 構造表達式:比如一個正常的代數式(叫他infix), a + b * c + ( d * e + f ) * g , 轉化成表達式 a b c * + d e * f + g * +, 這個表達式我們叫他 postfix。(先規定優先級,加減的優先級最低,左括號優先級最高)
- 用於函數調用:因爲CPU一次只能執行一個命令,而寄存器也是公用的,當前函數 current() 在運行時,數據儲存在寄存器中,如果要調用另外一個函數 target(),而target() 也要求使用寄存器,爲了防止數據丟失並且在執行完 target()。能夠返回到 current() 繼續執行, 這時候就要把當前函數的重要數據儲存起來,壓入內存中的棧中( 包括變量的值和函數地址 )。這樣target()函數就可以無所顧忌的使用寄存器了。target() 函數執行結束就取棧頂的返回地址繼續執行 current()。
隊列:
- 打印機:當多個任務分配給打印機時,爲了防止衝突,創建一個隊列,把任務入隊,按先入先出的原則處理任務;
- 遠程服務器:當多個用戶要訪問遠程服務端的文件時,也用到隊列,滿足先來先服務的原則;
- 隊列理論:用來計算 預測用戶在隊中的等待時間,隊的長度等等問題;
一、使用列表實現堆棧和隊列
(1)堆棧:
letters = []
# Let's push some letters into our list
letters.append('c')
letters.append('a')
letters.append('t')
letters.append('g')
# Now let's pop letters, we should get 'g'
last_item = letters.pop()
print(last_item)
# If we pop again we'll get 't'
last_item = letters.pop()
print(last_item)
# 'c' and 'a' remain
print(letters) # ['c', 'a']
輸出:
g
t
['c', 'a']
(2)隊列:
fruits = []
# Let's enqueue some fruits into our list
fruits.append('banana')
fruits.append('grapes')
fruits.append('mango')
fruits.append('orange')
# Now let's dequeue our fruits, we should get 'banana'
first_item = fruits.pop(0)
print(first_item)
# If we dequeue again we'll get 'grapes'
first_item = fruits.pop(0)
print(first_item)
# 'mango' and 'orange' remain
print(fruits) # ['mango', 'orange']
輸出:
banana
grapes
['mango', 'orange']
二、使用Deque庫的堆棧和隊列
from collections import deque
# you can initialize a deque with a list
numbers = deque()
# Use append like before to add elements
numbers.append(99)
numbers.append(15)
numbers.append(82)
numbers.append(50)
numbers.append(47)
# You can pop like a stack
last_item = numbers.pop()
print(last_item) # 47
print(numbers) # deque([99, 15, 82, 50])
# You can dequeue like a queue
first_item = numbers.popleft()
print(first_item) # 99
print(numbers) # deque([15, 82, 50])
輸出:
47
deque([99, 15, 82, 50])
99
deque([15, 82, 50])