<big>編譯環境:python v3.5.0, mac osx 10.11.4</big>
什么是隊列
- 具有一定操作約束的線性表,只能在一端插入,在另一端刪除。
- 數據插入(入隊列,AddQ),數據刪除(DeleteQ)
-
先入先出(FIFO)
如同生活中的排隊買票,排在隊頭的先買票,排在隊尾的最后一個最后才能買票。
隊列的抽象數據類型描述
隊列的順序存儲(數組)實現
- 基礎實現:由一個數組和兩個指針構成,插入元素則是指向后的指針(rear)后移一位,刪除元素則把指向前的元素(front)后移一位,當隊列為空時兩個指針指向同一個位置。(queue.py)
# -- coding: utf-8 --
class Queue():
def init(self, maxSize): # 初始化隊列,頭和尾都指向-1
self._front = -1
self._rear = -1
self._q = [None] * maxSize
def addElem(self, element):
if self._rear == len(self._q)-1: # 如果rear指向了隊列的最后一個元素,則隊列滿了
print('it is a full queue!')
else:
self._rear += 1
self._q[self._rear] = element
print('add ' + str(element) + ' in Queue')
def deleteElem(self): # 刪除front指向的元素,并放回被刪除的元素
if self._front == self._rear: # 如果front 和 rear指向同一個元素,則隊列為空
print('it is an empty queue!')
else:
self._front += 1
value = self._q[self._front]
print('add ' + str(value) + ' in Queue')
self._q[self._front] = None # 刪除元素
return value - 順環隊列:顯然當上述隊列的實現不能充分的利用存儲空間,即當每個存儲單元只能存儲一次元素,當進行delete操作后,就一直空著了。這并不是我們想要的結果,所以為了高效的利用計算機存儲空間,我們一般利用順環隊列進行實現。
實現關鍵:對front和rear都采用<big>“加一取余”</big>的辦法來實現順序存儲的循環利用,且rear和front起始都指向位置0而不是1。(queue.py)
# -- coding: utf-8 --
class Queue():
def init(self, maxSize): # 初始化隊列,頭和尾都指向0
self._front = 0
self._rear = 0
self._q = [None] * maxSize
def addElem(self, element):
if (self._rear + 1) % len(self._q) == self._front: # 對rear進行加一取余數(實現循環利用),但到達最大數時歸到起始位置即0,1,2,3,4,0,1,2,3,4依次循環
print('it is a full queue!')
else:
self._q[self._rear] = element
self._rear = (self._rear + 1) % len(self._q)
#print(str(self._rear)+'----'+str(self._front))
print('add ' + str(element) + ' in Queue')
def deleteElem(self): # 刪除front指向的元素,并放回被刪除的元素
if self._front == self._rear: # 如果front 和 rear指向同一個元素,則隊列為空
print('it is an empty queue!')
else:
value = self._q[self._front]
self._q[self._front] = None # 刪除元素
self._front = (self._front + 1) % len(self._q) # 對rear進行加一取余數(實現循環利用),但到達最大數時歸到起始位置
print('delete ' + str(value) + ' out of Queue')return value
隊列的鏈式存儲(鏈表)實現
隊列的鏈式存儲結構也可以由單向鏈表實現。由于刪除操作作用在front頭,所以front指向頭節點。(queue_chain.py)
class Note():
def __init__(self,value=None,next=None):
self.value = value
self.next = next
class queueChain:
def __init__(self,front=None,rear=None):
self.front = front # fron指向表頭的指針
self.rear = rear # rear指向表尾的指針
def inQue(queue, value): # 入隊操作
newNote = Note(value)
if queue.front is None: # 鏈表為空,將front 賦值給表頭
queue.front = queue.rear = newNote
else:
queue.rear.next = newNote
queue.rear = newNote
print('add '+str(value)+' in the queue' )
def outQue(queue): # 出隊操作
if queue.front is None : # 如果front指向為空,則鏈表為空
print('it is an empty queue!')
else:
p = queue.front
element = p.value
if queue.front == queue.rear: # 如果前后指針指向一個元素,則全部重置為None
queue.front = queue.rear = None
else:
queue.front = p.next
del p # 釋放空間
print('delete ' + str(element) +' out of Queue')
return element