Python中堆、棧、佇列之間的區別

小小程序员ol發表於2024-08-15

一、佇列概念

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

2、在電腦科學中,佇列是一個集合,其中集合中的實體按順序儲存,集合上的主要(或唯一)操作是向後端位置新增實體,稱為入隊,前端位置並刪除實體,稱為出隊。這使得佇列成為先進先出(FIFO)資料結構。在FIFO資料結構中,新增到佇列的第一個元素將是第一個要刪除的元素。這相當於一旦新增新元素,在刪除新元素之前必須刪除之前新增的所有元素的要求。通常偷看或還輸入了前面的操作,返回前面元素的值而不使其出列。佇列是線性資料結構的示例,或者更抽象地是順序集合。

3、佇列提供電腦科學,運輸和運營研究中的服務,其中儲存和儲存諸如資料,物件,人或事件的各種實體以便稍後處理。在這些上下文中,佇列執行緩衝區的功能。佇列在計算機程式中很常見,它們被實現為與訪問例程耦合的資料結構,作為抽象資料結構或作為類的面嚮物件語言。常見的實現是迴圈緩衝區和連結串列。

  • 生活中典型的例項就是排隊,先到的人排在前面,可先得到服務,後到的人排在後面,並且不能插隊。
  • 計算機應用中典型的例項就是印表機,先傳送的列印任務可以先被執行,之後的都要排隊等候

二、Python實現

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

2、從理論上講,佇列的一個特徵是它沒有特定的容量。無論已包含多少元素,始終可以新增新元素。它也可以是空的,此時在再次新增新元素之前刪除元素是不可能的。

3、佇列的Python實現:

Queue.qsize() 返回佇列的大小

Queue.empty() 如果佇列為空,返回True,反之False

Queue.full() 如果佇列滿了,返回True,反之False,Queue.full 與 maxsize 大小對應

Queue.get()從佇列中移除並返回資料

Queue.get_nowait() 相當於Queue.get(False),非阻塞方法

Queue.put(item[, block[, timeout]])
將item放入佇列

  • timeout為正整數時,等待超時則丟擲Full異常

  • block為False時,有空間可將資料放入佇列,立即丟擲Full異常

Queue.task_done() 在完成一項工作之後,Queue.task_done()函式向任務已經完成的佇列傳送一個訊號。每個get()呼叫得到一個任務,接下來task_done()呼叫告訴佇列該任務已經處理完畢。

Queue.join() 實際上意味著等到佇列為空,再執行別的操作【執行緒阻塞,直到佇列中的所有任務處理完畢】

from Queue import Queue,LifoQueue,PriorityQueue
#先進先出佇列
q=Queue(maxsize=5)
#後進先出佇列
lq=LifoQueue(maxsize=6)
#優先順序佇列
pq=PriorityQueue(maxsize=5)
 
for i in range(5):
    q.put(i)
    lq.put(i)
    pq.put(i)
    
print "先進先出佇列:%s;是否為空:%s;多大,%s;是否滿,%s" %(q.queue,q.empty(),q.qsize(),q.full())
print "後進先出佇列:%s;是否為空:%s;多大,%s;是否滿,%s" %(lq.queue,lq.empty(),lq.qsize(),lq.full())
print "優先順序佇列:%s;是否為空:%s,多大,%s;是否滿,%s" %(pq.queue,pq.empty(),pq.qsize(),pq.full())
 
print q.get(),lq.get(),pq.get()
 
print "先進先出佇列:%s;是否為空:%s;多大,%s;是否滿,%s" %(q.queue,q.empty(),q.qsize(),q.full())
print "後進先出佇列:%s;是否為空:%s;多大,%s;是否滿,%s" %(lq.queue,lq.empty(),lq.qsize(),lq.full())
print "優先順序佇列:%s;是否為空:%s,多大,%s;是否滿,%s" %(pq.queue,pq.empty(),pq.qsize(),pq.full())

4、python的四種佇列操作

①LILO: 先進先出,只能在尾部插入元素,只能從頭部取出元素

from queue import Queue
q = Queue()    # 建立佇列物件
q.put(1)       # 佇列尾部插入元素
q.put(2)
q.put(3)
print(q.queue) # 檢視佇列中的所有元素
a = q.get()    # 返回並刪除佇列頭部元素
print(a)
print(q.queue) # 執行結果deque([2,3])

②LIFO:先進後出,類似棧

from queue import LifoQueue
lifoQueue = LifoQueue()  # 建立物件
lifoQueue.put(1)
lifoQueue.put(2)
lifoQueue.put(3)
print(lifoQueue.queue)
lifoQueue.get()          # 返回並刪除佇列尾部元素
print(lifoQueue.queue)   # 執行結果[1,2]

③優先佇列:佇列元素為元組型別,即(優先順序,資料)。

from queue import PrioritQueue as pq
pq = pq()        # 建立有限佇列
pq.put(1)
pq.put(4)
pq.put(3)  
print(pq.queue)  # 執行結果[1,3,4]
pq.get()         # 返回並刪除優先順序最低的元素
print(pq.queue)  # 執行結果[3,4]

④雙端佇列

#學習中遇到問題沒人解答?小編建立了一個Python學習交流群:531509025
>>> from collections import deque   #雙端佇列
>>> dequeQueue = deque(['Eric','John','Smith'])
>>> print(dequeQueue)
deque(['Eric', 'John', 'Smith'])
>>> dequeQueue.append('Tom')    #在右側插入新元素
>>> dequeQueue.appendleft('Terry')  #在左側插入新元素
>>> print(dequeQueue)
deque(['Terry', 'Eric', 'John', 'Smith', 'Tom'])
>>> dequeQueue.rotate(2)    #迴圈右移2次
>>> print('迴圈右移2次後的佇列',dequeQueue)
迴圈右移2次後的佇列 deque(['Smith', 'Tom', 'Terry', 'Eric', 'John'])
>>> dequeQueue.popleft()    #返回並刪除佇列最左端元素
'Smith'
>>> print('刪除最左端元素後的佇列:',dequeQueue)
刪除最左端元素後的佇列: deque(['Tom', 'Terry', 'Eric', 'John'])
>>> dequeQueue.pop()    #返回並刪除佇列最右端元素
'John'
>>> print('刪除最右端元素後的佇列:',dequeQueue)
刪除最右端元素後的佇列: deque(['Tom', 'Terry', 'Eric'])

堆、棧、佇列之間的區別

1、堆是在程式執行時,而不是在程式編譯時,申請某個大小的記憶體空間。即動態分配記憶體,對其訪問和對一般記憶體的訪問沒有區別。

2、棧就是一個桶,後放進去的先拿出來,它下面本來有的東西要等它出來之後才能出來。(後進先出)

3、佇列只能在隊頭做刪除操作,在隊尾做插入操作.而棧只能在棧頂做插入和刪除操作。(先進先出)

相關文章