隊列 (queue) 是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的后端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。
隊列符合先進先出[FIFO]的原則。因為要排隊的第一個項目,最終將是第一個要出列的項目,如在現實生活中的隊列,先來的站在隊列前面,后來的就只能站在隊列后面啦。
隊列有兩種實現形式,分為兩種:數組和鏈表。
在接下來的內容里,我們將以鏈表的形式實現隊列,逐步介紹具體功能是如何實現的。
1. 創建 Node 類
創建一個 Node 的類,作為基礎數據結構:鏈點,並初始化對應的內參。
具體實現代碼如下:
class Node(object): def __init__(self,elem,next=None): self.elem = elem #表示對應的元素值 self.next=next #表示下一個鏈接的鏈點
2. 創建 Queue 類
創建一個 Queue 的類,以鏈表形式的隊列,並初始化對應的內參。
具體實現代碼如下:
class Queue(object): def __init__(self): self.head = None #頭部鏈點為 None self.rear = None #尾部鏈點為 None
3. 添加 is_empty 函數
添加一個 is_empty 的函數,功能是判斷隊列是否為空
具體實現代碼如下:
def is_empty(self): return self.head is None #判斷隊列是否為空
4. 添加 enqueue 函數
添加一個 enqueue(elem) 函數,功能是往隊列中添加一個 elem 元素
流程如下:
- Vertex vtx = new Vertex(v) 初始化一個新的點
- tail.next = vtx 隊列尾部的后繼是這個新的點
- tail = vtx 然后讓隊列尾部指針指向這個新的點
效果演示:往已知隊列[29,9,53]里面添加一個 80 元素
具體實現代碼如下:
def enqueue(self, elem): p = Node(elem) #初始化一個新的點 if self.is_empty(): self.head = p #隊列頭部為新的鏈點 self.rear = p #隊列尾部為新的鏈點 else: self.rear.next = p #隊列尾部的后繼是這個新的點 self.rear =p #然后讓隊列尾部指針指向這個新的點
5. 添加 dequeue 函數
添加一個 dequeue() 函數,功能是從隊列頭部刪除一個元素
流程如下:
- 先判斷隊列是否為空,為空即退出 dequeue 操作,不為空即繼續后續操作
- temp = head 設置一個 temp 指針,使它的指針指向隊列頭部
- head = head.next 隊列頭部指針,使之指向隊列頭部的后繼(即隊列頭部元素出隊)
- delete temp 刪除 temp 指針
效果演示:對已知隊列[29,9,53,80] 刪除頭部元素
具體實現代碼如下:
def dequeue(self): if self.is_empty(): #判斷隊列是否為空 print('Queue_is_empty') #若隊列為空,則退出 dequeue 操作 else: result = self.head.elem #result為隊列頭部元素 self.head = self.head.next #改變隊列頭部指針位置 return result #返回隊列頭部元素
6. 添加 peek 函數
添加一個 peek() 函數,功能是查看隊列頭部的元素
流程如下:
- 判斷隊列是否為空,為空即返回 NOT_FOUND
- 隊列如果不為空,返回隊列頭部元素
具體代碼實現如下:
def peek(self): if self.is_empty(): #判斷隊列是否為空 print('NOT_FOUND') #為空則返回 NOT_FOUND else: return self.head.elem #返回隊列頭部元素
7. 添加 print_queue 函數
添加一個 print_queue() 函數,功能是展現隊列的元素
def print_queue(self): print("queue:") temp=self.head myqueue=[] #暫時存放隊列數據 while temp is not None: myqueue.append(temp.elem) temp=temp.next print(myqueue)
最終代碼如下:
class Node(object): def __init__(self,elem,next=None): self.elem = elem #表示對應的元素值 self.next=next #表示下一個鏈接的鏈點 class Queue(object): def __init__(self): self.head = None #頭部鏈點為 None self.rear = None #尾部鏈點為 None def is_empty(self): return self.head is None #判斷隊列是否為空 def enqueue(self, elem): p = Node(elem) #初始化一個新的點 if self.is_empty(): self.head = p #隊列頭部為新的鏈點 self.rear = p #隊列尾部為新的鏈點 else: self.rear.next = p #隊列尾部的后繼是這個新的點 self.rear =p #然后讓隊列尾部指針指向這個新的點 def dequeue(self): if self.is_empty(): #判斷隊列是否為空 print('Queue_is_empty') #若隊列為空,則退出 dequeue 操作 else: result = self.head.elem #result為隊列頭部元素 self.head = self.head.next #改變隊列頭部指針位置 return result #返回隊列頭部元素 def peek(self): if self.is_empty(): #判斷隊列是否為空 print('NOT_FOUND') #為空則返回 NOT_FOUND else: return self.head.elem #返回隊列頭部元素 def print_queue(self): print("queue:") temp=self.head myqueue=[] #暫時存放隊列數據 while temp is not None: myqueue.append(temp.elem) temp=temp.next print(myqueue)
復雜度分析
隊列屬於常見的一種線性結構,對於出隊和進隊而言,時間復雜度都為 O(1)
隊列有兩種實現形式,數組和鏈表。我們在前面已經介紹了如何用鏈表實現的隊列,這里就不再贅述,直接給出另一種用數組實現的隊列代碼,供大家學習參考。
形式:用數組實現
class Queue(): def __init__(self): self.entries = [] #表示隊列內的參數 self.length = 0 #表示隊列的長度 self.front=0 #表示隊列頭部位置 def enqueue(self, item): self.entries.append(item) #添加元素到隊列里面 self.length = self.length + 1 #隊列長度增加 1 def dequeue(self): self.length = self.length - 1 #隊列的長度減少 1 dequeued = self.entries[self.front] #隊首元素為dequeued self.front-=1 #隊首的位置減少1 self.entries = self.entries[self.front:] #隊列的元素更新為退隊之后的隊列 return dequeued def peek(self): return self.entries[0] #直接返回隊列的隊首元素 請點擊選擇想要使用的環境 默認環境