1. 程式人生 > 實用技巧 >資料結構與演算法-棧、佇列

資料結構與演算法-棧、佇列

  • 特性:先進後出的資料結構
  • 棧頂,棧尾
    • 入棧:向棧頂新增元素(從棧頂向棧底新增元素)
    • 出棧:從棧頂獲取元素(從棧頂取出元素)
  • 應用:每個 web 瀏覽器都有一個返回按鈕。當你瀏覽網頁時,這些網頁被放置在一個棧中(實際是網頁的網址)。你現在檢視的網頁在頂部,你第一個檢視的網頁在底部。如果按‘返回’按鈕,將按相反的順序瀏覽剛才的頁面。
  • Stack() 建立一個空的新棧。 它不需要引數,並返回一個空棧。
  • push(item)將一個新項新增到棧的頂部。它需要 item 做引數並不返回任何內容。
  • pop() 從棧中刪除頂部項。它不需要引數並返回 item 。棧被修改。
  • peek() 從棧返回頂部項,但不會刪除它。不需要引數。 不修改棧。
  • isEmpty() 測試棧是否為空。不需要引數,並返回布林值。
  • size() 返回棧中的 item 數量。不需要引數,並返回一個整數。
class Stack():
    def __init__(self):
        self.items = []
        
    def push(self, item):
        self.items.append(item)
        
    def pop(self):
        return self.items.pop()
    
    
def isEmpty(self): return self.items == [] def size(self): return len(self.items) # 返回棧頂元素的下標 def peek(self): return len(self.items) - 1

佇列

  • 佇列:先進先出
    • 隊頭:直接從隊頭出佇列(取出元素)
    • 隊尾:從隊尾新增元素
  • 應用場景:
    • 我們的計算機實驗室有 30 臺計算機與一臺印表機聯網。當學生想要列印時,他們的列印任務與正在等待的所有其他列印任務“一致”。第一個進入的任務是先完成。如果你是最後一個,你必須等待你前面的所有其他任務列印
  • Queue() 建立一個空的新佇列。 它不需要引數,並返回一個空佇列。
  • enqueue(item) 將新項新增到隊尾。 它需要 item 作為引數,並不返回任何內容。
  • dequeue() 從隊首移除項。它不需要引數並返回 item。 佇列被修改。
  • isEmpty() 檢視佇列是否為空。它不需要引數,並返回布林值。
  • size() 返回佇列中的項數。它不需要引數,並返回一個整數。
class Queue():
    def __init__(self):
        self.items = []
    
    def enqueue(self,item):
        self.items.insert(0,item)
        
    def dequeue(self):
        return self.items.pop()
    
    def size(self):
        return len(self.items)
    
    def isEmpty(self):
        return self.items == []

雙端佇列

  • 同同列相比,有兩個頭部和尾部。可以在雙端進行資料的插入和刪除,提供了單資料結構中棧和佇列的特性
  • Deque() 建立一個空的新 deque。它不需要引數,並返回空的 deque。
  • addFront(item) 將一個新項新增到 deque 的首部。它需要 item 引數 並不返回任何內容。
  • addRear(item) 將一個新項新增到 deque 的尾部。它需要 item 引數並不返回任何內容。
  • removeFront() 從 deque 中刪除首項。它不需要引數並返回 item。deque 被修改。
  • removeRear() 從 deque 中刪除尾項。它不需要引數並返回 item。deque 被修改。
  • isEmpty() 測試 deque 是否為空。它不需要引數,並返回布林值。
  • size() 返回 deque 中的項數。它不需要引數,並返回一個整數。
class Dequeue():
    def __init__(self):
        self.items = []
        
    def addFont(self,item):
        self.items.append(item)
        
    def addRear(self,item):
        self.items.insert(0,item)
        
    def removeFont(self):
        return self.items.pop()
    
    def removeRear(self):
        return self.items.pop(0)
    
    def isEmpty(self):
        return self.items == []
    
    def size(self):
        return len(self.items)

應用

案例一:燙手的山芋(佇列應用)

  • 燙手山芋遊戲介紹:6個孩子圍城一個圈,排列順序孩子們自己指定。第一個孩子手裡有一個燙手的山芋,需要在計時器計時1秒後將山芋傳遞給下一個孩子,依次類推。規則是,在計時器每計時7秒時,手裡有山芋的孩子退出遊戲。該遊戲直到剩下一個孩子時結束,最後剩下的孩子獲勝。請使用佇列實現該遊戲策略,排在第幾個位置最終會獲勝。
  • 分析:
    • 1.每輪遊戲的時間為7s
    • 2.山芋在一輪遊戲中會被傳遞幾次:6次
    • 3.一輪遊戲結束後,需要淘汰一個孩子,孩子需要從佇列中剔除
      • 佇列只能從隊頭位置取出元素
      • 保證手裡有山芋的孩子永遠在隊頭的位置
# 將6個孩子加入到佇列中
kids = ['A','B','C','D','E','F']
q = Queue()
for kid in kids:
    q.enqueue(kid)

while q.size() > 1: # 結束遊戲的條件
    # 開始一輪遊戲
    for i in range(6):# 山芋傳遞的次數
        kid = q.dequeue() # 將隊頭的孩子取出
        q.enqueue(kid) # 將隊頭的孩子取出,新增到隊尾
    # 一輪遊戲結束需要將隊頭元素出佇列(將手中有山芋的孩子淘汰遊戲)
    q.dequeue() 

print(q.dequeue())  # 檢視最後剩下的孩子

E

案例二:兩個佇列實現棧(用倆個先進先出實現先進後出)

q1 = Queue()
q2 = Queue()
items = [1,2,3,4,5,6]
for item in items:
    q1.enqueue(item)

while q1.size() >= 1:
    # 將q1中的前n-1個元素取出加入到q2中
    while q1.size() > 1:
        item = q1.dequeue()  # 將q1留1個,其他元素取出放入q2
        q2.enqueue(item)
    print(q1.dequeue()) # 取出q1剩餘的最後一個元素
    q1,q2 = q2,q1  # 將q1,q2互換

6
5
4
3
2
1

案例三:兩個棧實現佇列(用倆個先進後出實現先進先出)

s1 = Stack()
s2 = Stack()
items = [1,2,3,4,5,6]
for item in items:
    s1.push(item)
    
while s1.size() >= 1:
    while s1.size() > 1:
        item = s1.pop()
        s2.push(item) # s2:6,5,4,3,2  s1:1
    print(s1.pop()) # s2:6,5,4,3,2  s1:空
    while s2.size() >= 1:
        item = s2.pop()  # s2:空  s1:2,3,4,5,6
        s1.push(item)

1
2
3
4
5
6

案例四:迴文檢查(雙端佇列)

雙端佇列應用案例:迴文檢查

  • 迴文是一個字串,讀取首尾相同的字元,例如,radar toot madam。
def isHuiWen(aString):
    de = Dequeue()
    for ch in aString:
        de.addFont(ch)
    ex = True
    while de.size()>1:
        # 取出最前和最後元素對比
        if de.removeFont() != de.removeRear():
            ex = False
    return ex

print(isHuiWen('abaa'))