今天我們來到了迴圈佇列這一節,之前的文章中,我介紹過了用python自帶的列表來實現佇列,這是最簡單的實現方法。
但是,我們都知道,在列表中刪除第一個元素和刪除最後一個元素花費的時間代價是不一樣的,刪除列表的第一個元素,那麼在它之後的所有元素都要進行移動。所以當列表特別長的時候,這個代價就比較明顯了。我們本文介紹的迴圈佇列可以避免這個問題,同樣我們上篇文章提到的用連結串列實現的方法也可以避免。
下面,我們來介紹迴圈佇列。
循壞佇列
迴圈佇列,就是將普通的佇列首尾連線起來, 形成一個環狀,並分別設定首尾指標,用來指明佇列的頭和尾。每當我們插入一個元素,尾指標就向後移動一位,當然,在這裡我們佇列的最大長度是提前定義好的,當我們彈出一個元素,頭指標就向後移動一位。
這樣,列表中就不存在刪除操作,只有修改操作,從而避免了刪除前面節點造成的代價大的問題。
好,話不多說,我們用程式碼來實現一下
class Loopqueue:
def __init__(self, length):
self.head = 0
self.tail = 0
self.maxSize = length
self.cnt = 0
self.__list = [None]*length
這裡同樣,我們定義一個佇列類,在例項化迴圈佇列的時候,要求指定佇列的大小,除了首尾指標以及佇列最大長度之外,我們還宣告一個表示佇列當前長度的屬性cnt。
接下來我們給佇列增加一些操作:
- 判空
def isEmpty(self):
return self.cnt == 0
- 判滿
def isFull(self):
return self.cnt == self.maxSize
- 新增元素
def push(self, data):
if self.isFull():
return False
if self.isEmpty():
self.__list[0] = data
self.head = 0
self.tail = 0
self.cnt = 1
return True
self.tail = (self.tail+1)%self.maxSize
self.cnt += 1
self.__list[self.tail] = data
return True
- 彈出元素
def pop(self):
if self.isEmpty():
return False
data = self.__list[self.head]
self.head = (self.head+1)%self.maxSize
self.cnt -= 1
return data
- 清空佇列
def clear(self):
self.head = 0
self.tail = 0
self.cnt = 0
return True
- 定義len和print函式
def __len__(self):
return self.cnt
def __str__(self):
s = ''
for i in range(self.cnt):
index = (i + self.head) % self.maxSize
s += str(self.__list[index])+' '
return s
OK,我們的迴圈佇列類就定義好了,如果你看過介紹佇列的文章,就會發現迴圈佇列和普通佇列的操作在邏輯上還是有一些相似的。
程式碼並不難,相信你已經完全理解了,自己動手操作一下吧。
你還了解哪些佇列型別呢?留言告訴我吧。