1. 程式人生 > >佇列的Python實現與例項分析

佇列的Python實現與例項分析

佇列是隻有一端可以進行插入操作,而另一端可以進行刪除操作的有序線性儲存結構,滿足先進先出的約束。

生活中典型的例項就是排隊,先到的人排在前面,可先得到服務,後到的人排在後面,並且不能插隊。

計算機應用中典型的例項就是印表機,先發送的列印任務可以先被執行,之後的都要排隊等候

Python實現

在 Python 中,和棧一樣,同樣可以用列表作為佇列的底層實現,只需要確定列表的哪一端作為佇列的頭,也即刪除操作端,哪一端作為佇列的尾,也即插入操作端。同時,把佇列抽象為類,佇列的先進先出操作實現為類的方法

假定隊尾在列表中的位置為 0。這允許我們使用列表上的插入函式向隊尾新增新元素。彈出操作可用於刪除隊首的元素(列表的最後一個元素)。這樣入隊的複雜度為 O(n),出隊為 O(1)。如果隊尾和隊首在列表中的位置換一下,則入隊的複雜度為 O(1),出隊為 O(n)。

以下為按照前面一種方式的佇列的Python實現

Queue 實現一個佇列類,可通過 Queue() 建立一個空佇列

is_empty 操作判斷佇列是否為空

enqueue 操作將新元素插入到列尾

dequeue 操作將彈出並刪除隊首的元素

size 操作返回佇列的大小

class Queue:
    def __init__(self):
        self.items=[]
    def is_empty(self):
        return 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)

以上為佇列的最簡單實現,對比棧的實現,可以看出兩者非常相像,只在插入操作上有所不同。

應用例項

約瑟夫問題:n個人圍成一個圈,每個人分別標註為1、2、…、n,要求從1號從1開始報數,報到k的人出圈,接著下一個人又從1開始報數,如此迴圈,直到只剩最後一個人時,該人即為勝利者。

解約瑟夫問題的一種方法是模擬這個過程,模擬的載體可以是佇列,也可以是連結串列,下面就用列隊來模擬這個過程

迴圈報數的過程可以看作是一個先報數先出的過程,用佇列來模擬時,將當前報數的人彈出,如果報的不是k時,再插入到隊尾,從而得以迴圈,如果報的是k,則拋棄。直至剩下最後一個人。

下面是在生成 Queue 類的基礎下,Python 解決約瑟夫問題的一個例項程式碼,以實際人名來模擬n個人,報數為7時刪除,輸出最後的勝利者。

#約瑟夫問題模擬函式
def circle(k,nameList):
    queue1=Queue()
    for i in range(len(nameList)):  #將名字列表逐個插入佇列
        queue1.enqueue(nameList[i])
    i=1
    while queue1.size()!=1:
        temp=queue1.dequeue()       #叫到哪個將哪個彈出
        if i!=k:
            queue1.enqueue(temp)    #不是第k個再插入
        else :
            i=0                     #是第k個重新計數
        i+=1
    return queue1.dequeue()
#主函式
if __name__=='__main__':
    nameList=["Bill","David","Susan","Jane","Kent","Brad"]
    print(circle(7,nameList))
#輸出結果
Kent