Python演算法實戰系列之佇列

發表於2017-04-04

佇列(queue),是先進先出(FIFO, First-In-First-Out)的線性表,在具體應用中通常用連結串列或者陣列來實現,佇列只允許在後端(稱為rear)進行插入操作,在前端(稱為front)進行刪除操作,佇列的操作方式和堆疊類似,唯一的區別在於佇列只允許新資料在後端進行新增。

摘錄維基百科

如圖所示

Python演算法實戰系列之佇列

佇列的介面

一個佇列至少需要如下介面:

介面 描述
add(x) 入隊
delete() 出隊
clear() 清空佇列
isEmpty() 判斷佇列是否為空
isFull() 判斷佇列是否未滿
length() 佇列的當前長度
capability() 佇列的容量

然而在Python中,可以使用collections模組下的deque函式,deque函式提供了佇列所有的介面,那麼先讓我門看看佇列deque函式提供了那些API把:

collections.deque是雙端佇列,即左右兩邊都是可進可出的

方法 描述
append(x) 在佇列的右邊新增一個元素
appendleft(x) 在佇列的左邊新增一個元素
clear() 從佇列中刪除所有元素
copy() 返回一個淺拷貝的副本
count(value) 返回值在佇列中出現的次數
extend([x..]) 使用可迭代的元素擴充套件佇列的右側
extendleft([x..]) 使用可迭代的元素擴充套件佇列的右側
index(value, [start, [stop]]) 返回值的第一個索引,如果值不存在,則引發ValueError。
insert(index, object) 在索引之前插入物件
maxlen 獲取佇列的最大長度
pop() 刪除並返回最右側的元素
popleft() 刪除並返回最左側的元素
remove(value) 刪除查詢到的第一個值
reverse() 佇列中的所有元素進行翻轉
rotate() 向右旋轉佇列n步(預設n = 1),如果n為負,向左旋轉。

現在我們在Python中測試下這些個API的使用吧。

入隊操作

出隊操作

其他的API

例項

二項式係數

題目

編寫程式,求二項式係數表中(楊輝三角)第K層系列數

思路

  1. 把第K行的係數儲存在佇列中
  2. 依次出隊K層的係數(每行最後一個1不出隊),並推算K+1層係數,新增到隊尾,最後在隊尾新增一個1,便變成了k+1行。

解決程式碼

劃分無衝突子集

題目

某動物園搬家,要運走N種動物,老虎與獅子放在一起會大家,大象與犀牛放在一個籠子會打架,野豬和野狗放在一個籠子裡會打架,現在需要我們設計一個演算法,使得裝進同一個籠子的動物互相不打架。

思路

  1. 把所有動物按次序入隊
  2. 建立一個籠子(集合),出隊一個動物,如果和籠子內動物無沖沖突則新增到該籠子,有衝突則新增到隊尾,等待進入新籠子
  3. 由於佇列先進先出的特性,如果當前出隊動物的index不大於前一個出隊動物的index,說明當前佇列中所有動物已經嘗試過進入且進入不了當前籠子,此時建立信的籠子(集合)

解決程式碼

數字變換

題目

對於一對正整數a,b,對a只能進行加1,減1,乘2操作,問最少對a進行幾次操作能得到b?

例如:

  1. a=3,b=11: 可以通過322-1,3次操作得到11;
  2. a=5,b=8:可以通過(5-1)*2,2次操作得到8;

思路

本題用廣度優先搜尋,尋找a到b狀態遷移最短路徑,對於每個狀態s,可以轉換到撞到s+1,s-1,s*2:

  1. 把初始化狀態a入隊;
  2. 出隊一個狀態s,然後s+1,s-1,s*2入隊;
  3. 反覆迴圈第二步驟,直到狀態s為b;

解決程式碼

相關文章