Python数据结构学习笔记——队列和双端队列
目錄
- 一、隊列的定義
- 二、隊列 實現(xiàn)步驟分析
- 三、隊列的Python實現(xiàn)代碼
- 四、隊列的應用
- 六人傳土豆游戲
- 五、雙端隊列的定義
- 六、雙端隊列 實現(xiàn)步驟分析
- 七、雙端隊列的Python實現(xiàn)代碼
- 八、雙端隊列的應用
- 回文檢測器
- 結(jié)語
一、隊列的定義
隊列和棧一樣,也是元素的有序集合,其元素的順序取決于添加順序或移除順序,它也有兩端,稱作頭部和尾部,棧中元素的添加操作和移除操作與棧不一樣,添加操作發(fā)生在隊列的尾部,移除操作發(fā)生在隊列的頭部。
隊列中最先添加的元素將最先被移除,隊列的排序原則被稱作FIFO,即先進先出,最先添加的元素在隊列頭部,它最先最移出隊列。
這種排列方式可以比喻成日常生活中的排隊,很多人排成一隊,所有的人從隊的一端入隊,從另一端出隊,其中不能插隊,后到的人若想進入隊列,只能從隊尾進入隊列。
隊列的相關(guān)應用例子:
在操作系統(tǒng)使用一些隊列來控制計算機進程。
調(diào)度機制往往基于一個隊列算法,其目標是盡可能快地執(zhí)行程序,同時服務盡可能多的用戶。在打字時,我們有時會發(fā)現(xiàn)字符出現(xiàn)的速度比擊鍵速度慢。這是由于計算機正在做其他的工作。擊鍵操作被放入一個類似于隊列的緩沖區(qū),以便對應的字符按正確的順序顯示。
二、隊列 實現(xiàn)步驟分析
與棧一樣,通過Python中的類與對象,在類中定義幾個方法,使用列表來實現(xiàn)隊列的相關(guān)操作,這里是將列表的末尾作為隊列的頭部,隊列的尾部是列表下標為0處的位置,隊列的操作有:
1、創(chuàng)建一個空隊列,通過構(gòu)造方法創(chuàng)建一個空列表;
2、向隊列(尾部)中添加元素,通過列表中的insert()實現(xiàn)添加新元素至隊列中,由于是向隊列尾部添加元素,添加列表中的第一個元素,即下標為0的元素;
def add(self, item):self.items.insert(0, item) # 在隊列的尾部添加元素,它需要一個元素作為參數(shù)3、刪除隊列頭部元素,通過列表中的pop()實現(xiàn)刪除隊列頭部元素,由于未指定參數(shù),所以該方法刪除列表中的末尾元素,即刪除的是隊列頭部元素;
def delete(self):return self.items.pop() # 刪除隊列頭部的元素,不需要參數(shù),它會返回一個元素,并修改隊列的內(nèi)容4、返回隊列的頭部元素,通過len()取得隊列(列表)的長度,由于列表的下標是從0開始,所以要減1,即可索引返回第一位元素;
def display(self):return self.items[len(self.items) - 1] # 返回隊列的頭部元素5、檢查隊列是否為空,通過比較運算符“==”比較隊列是否為空,若為空,則返回布爾值False,若不為空,則返回True;
def isEmpty(self):return self.items == [] # 檢查隊列是否為空,不需要參數(shù),且返回一個布爾值來表示6、返回隊列中元素數(shù)目,通過len()取所有元素的值,即返回隊列中元素的數(shù)目。
def size(self):return len(self.items) # 返回隊列中元素的數(shù)目,不需要參數(shù),卻返回一個整數(shù)來表示三、隊列的Python實現(xiàn)代碼
完整代碼如下:
# 通過列表實現(xiàn)隊列的操作 class Queue:def __init__(self):self.items = [] # 創(chuàng)建一個空隊列,不需要參數(shù),且會返回一個空隊列def add(self, item):self.items.insert(0, item) # 在隊列的尾部添加元素,它需要一個元素作為參數(shù)def delete(self):return self.items.pop() # 刪除隊列頭部的元素,不需要參數(shù),它會返回一個元素,并修改隊列的內(nèi)容def display(self):return self.items[len(self.items) - 1] # 返回隊列的頭部元素def isEmpty(self):return self.items == [] # 檢查隊列是否為空,不需要參數(shù),且返回一個布爾值來表示def size(self):return len(self.items) # 返回隊列中元素的數(shù)目,不需要參數(shù),卻返回一個整數(shù)來表示# 測試 q = Queue()# q是一個新創(chuàng)建的空隊列,創(chuàng)建一個對象,即對象名稱=類名稱() print(q.isEmpty()) # 查詢隊列是否為空 print(q.size()) # 返回隊列中元素的數(shù)目 q.add(False) # 在隊列的尾部添加一個元素 print(q.display())# 返回隊列的頭部元素 q.add("qwet") q.add(0) print(q.display()) print(q.size()) q.delete() # 刪除隊列頭部的元素 print(q.display()) print(q.size()) print(q.isEmpty())運行結(jié)果如下:
四、隊列的應用
六人傳土豆游戲
六個人傳土豆游戲可模擬為隊列的循環(huán),通過隊列來模擬一個環(huán),即隊列頭部的出隊移至尾部,然后入隊進入隊列的尾部從而一直循環(huán)傳下去。在出隊和入隊N次之后,此時位于隊列頭部的人出局,新一輪的游戲開始,如此反復像一個圓環(huán)一樣依次循環(huán)下去,直到隊列中只剩下一個名字,即最后隊伍的元素數(shù)目為1。
定義一個Pass()函數(shù),傳遞土豆的常量為7,首先通過一個for循環(huán)遍歷參加傳遞土豆游戲的所有人使其都添加到隊列中,通過add(name_people)方法實現(xiàn)程序?qū)崿F(xiàn),name_people參數(shù)可傳入一個列表,然后通過while循環(huán)條件為隊列中的元素是否大于1,若大于1則while循環(huán)一直執(zhí)行其內(nèi)部代碼塊下去,在while循環(huán)內(nèi)根據(jù)所輸入的傳遞土豆的常量通過for循環(huán)中的range()函數(shù)確定相應的循環(huán)次數(shù),然后依次將所刪除的頭部元素再添加到隊列的尾部,若循環(huán)次數(shù)(傳遞土豆的常量)達到后,此時刪除隊列頭部的元素,該人出局;若直到隊伍的元素數(shù)目等于1時,結(jié)束while循環(huán)返回隊列中的只剩下的那個元素,完整代碼及解析如下:
運行結(jié)果如下:
我們可以對六人傳土豆游戲進行進一步的修改,比如允許隨機計數(shù),從而使每一輪的結(jié)果都不可預測,從而使游戲更加公平,由于是隨機計數(shù),可以使用random模塊來生成隨機整數(shù),選定一個范圍使計算機自動生成。
改進后的六人傳土豆游戲程序代碼及解析如下:
運行結(jié)果如下,每次產(chǎn)生的計數(shù)常量值不同導致結(jié)果不同:
第一次運行:
第二次運行:
五、雙端隊列的定義
雙端隊列與隊列類似,它有前、后兩端,但無論是添加元素或刪除元素都可以在兩端實現(xiàn),它的排序原則可以為棧的后進先出,也可以為隊列的先進先出,這取決于使用者,可以說雙端隊列是棧和隊列的結(jié)合。
六、雙端隊列 實現(xiàn)步驟分析
通過Python中的類與對象,在類中定義幾個方法,使用列表來實現(xiàn)雙端隊列的相關(guān)操作,這里是將列表的末尾作為雙端隊列的前端,雙端隊列的后端是列表下標索引為0的位置,雙端隊列的操作有:
1、創(chuàng)建一個空雙端隊列,通過構(gòu)造方法創(chuàng)建一個空列表;
2、向雙端隊列兩端添加元素,分為向雙端隊列的前端或后端添加元素,前端通過append()方法向列表末尾添加元素,即向雙端隊列的前端添加;后端通過insert()方法在列表下標為0處列表的第一位元素,即雙端隊列的后端添加;
def addFront(self, item):self.items.append(item) # 在雙端隊列的前端添加元素,它需要一個元素作為參數(shù)def addRear(self, item):self.items.insert(0, item) # 在雙端隊列的后端添加元素,它需要一個元素作為參數(shù)3、刪除雙端隊列兩端元素,分為刪除雙端隊列的前端元素和刪除雙端隊列的后端元素,都通過使用pop()方法,前端不需要指定參數(shù),使其刪除列表的末尾元素,即雙端隊列的前端元素;后端指定參數(shù)為0,使其刪除列表中下標為0的元素,即列表的第一位元素,從而刪除雙端的后端元素;
def deleteFront(self):return self.items.pop() # 刪除雙端隊列前端的元素,不需要參數(shù),它會返回一個元素,并修改雙端隊列的內(nèi)容def deleteRear(self):return self.items.pop(0) # 刪除雙端隊列后端的元素,不需要參數(shù),它會返回一個元素,并修改雙端隊列的內(nèi)容4、返回雙端隊列的兩端元素,通過len()先取得列表的長度,由于下標是從0開始,所以要減1,從而索引得到雙端隊列的前端元素;通過索引列表下標為0的元素得到雙端隊列的后端元素;
def displayFront(self):return self.items[len(self.items) - 1] # 返回雙端隊列的前端元素def displayRear(self):return self.items[0] # 返回雙端隊列的后端元素5、檢查雙端隊列是否為空,通過比較運算符“==”比較隊列是否為空,若為空,則返回布爾值False,若不為空,則返回True;
def isEmpty(self):return self.items == [] # 檢查雙端隊列是否為空,不需要參數(shù),且返回一個布爾值來表示6、返回雙端隊列中元素數(shù)目,通過len()取所有元素的值,即返回隊列中元素的數(shù)目。
def size(self):return len(self.items) # 返回雙端隊列中元素的數(shù)目,不需要參數(shù),卻返回一個整數(shù)來表示七、雙端隊列的Python實現(xiàn)代碼
完整代碼如下:
# 通過列表實現(xiàn)雙端隊列的操作 class Deque:def __init__(self):self.items = [] # 創(chuàng)建一個空雙端隊列,不需要參數(shù),且會返回一個空雙端隊列def addFront(self, item):self.items.append(item) # 在雙端隊列的前端添加元素,它需要一個元素作為參數(shù)def addRear(self, item):self.items.insert(0, item) # 在雙端隊列的后端添加元素,它需要一個元素作為參數(shù)def deleteFront(self):return self.items.pop() # 刪除雙端隊列前端的元素,不需要參數(shù),它會返回一個元素,并修改雙端隊列的內(nèi)容def deleteRear(self):return self.items.pop(0) # 刪除雙端隊列后端的元素,不需要參數(shù),它會返回一個元素,并修改雙端隊列的內(nèi)容def displayFront(self):return self.items[len(self.items) - 1] # 返回雙端隊列的前端元素def displayRear(self):return self.items[0] # 返回雙端隊列的后端元素def isEmpty(self):return self.items == [] # 檢查雙端隊列是否為空,不需要參數(shù),且返回一個布爾值來表示def size(self):return len(self.items) # 返回雙端隊列中元素的數(shù)目,不需要參數(shù),卻返回一個整數(shù)來表示# 測試 d = Deque() # d是一個新創(chuàng)建的空雙端隊列,創(chuàng)建一個對象,即對象名稱=類名稱() print(d.isEmpty()) # 檢查雙端隊列是否為空 print(d.size()) # 返回雙端隊列中元素的數(shù)目 d.addFront(123456) # 向雙端隊列的前端添加元素 d.addFront("45@d") d.addRear("2021-1-14") # 向雙端隊列的后端添加元素 d.addRear("Z") print(d.size()) print(d.displayFront()) # 返回雙端隊列的前端元素 print(d.displayRear()) # 返回雙端隊列的后端元素 d.deleteFront() # 刪除雙端隊列的前端元素 print(d.size()) print(d.displayFront()) d.deleteRear() # 刪除雙端隊列的后端元素 print(d.size()) print(d.displayRear()) print(d.isEmpty())運行結(jié)果如下:
測試圖例:
八、雙端隊列的應用
回文檢測器
回文是指正著讀和反著讀都一樣的字符串,即成對稱的字符串,例如rar、toot、12321等等,我們可以通過一個雙端隊列來存儲字符串中的字符,通過從左往右的順序?qū)⒆址械淖址砑拥诫p端隊列的后端,然后通過定義一個條件,只有當雙端隊列的前端和后端相同時,才相互抵消刪除元素。一直這樣刪除下去,若輸入的字符串字符數(shù)為偶數(shù),則最后將沒有字符;若輸入的字符串字符數(shù)為奇數(shù),則最后只剩下一個字符,從而達到檢測回文的目的。
回文檢測器的完整代碼及解析如下:
運行結(jié)果如下:
結(jié)語
參考書籍:《Python數(shù)據(jù)結(jié)構(gòu)與算法分析 第2版》
[美] 布拉德利·米勒(Bradley N. Miller) 戴維·拉努姆(DavidL. Ranum)|譯者:呂能 刁壽鈞
以上就是本次Python數(shù)據(jù)結(jié)構(gòu)學習筆記棧的全部內(nèi)容,篇幅較長,感謝您的閱讀和支持,若有表述或代碼中有不當之處,望指出!您的指出和建議能給博主帶來很大的動力!!!
總結(jié)
以上是生活随笔為你收集整理的Python数据结构学习笔记——队列和双端队列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python数据结构学习笔记——栈
- 下一篇: Python数据结构学习笔记——链表:无