0x00 棧(stack)
棧是一種lifo(後進先出)的資料結構,有入棧(push)、出棧(pop)兩種操作,且只能操作棧頂元素。
在python中有多種可以實現棧的資料結構。
1、list
list是python內建的列表資料結構,它支援棧的特性,有入棧和出棧操作。只不過用list實現棧效能不是特別好。
因為list內部是通過乙個動態擴容的陣列來實現的。當增減元素時就有可能會觸發擴容操作。如果在list的頭部增減元素,也會移動整個列表。
s.pop()3
s.pop()『two』
s.pop()『one』
s.pop()indexerror: pop from empty list
2、collections.deque
deque類是一種雙端佇列。在python中它就是乙個雙向列表,可以以常用時間在兩端執行新增和刪除元素的操作,非常高效,所以它既可以實現棧也可以實現佇列。
如果要在python實現乙個棧,那麼應該優先選擇deque,而不是list。
s.pop()『code』
s.pop()『sleep』
s.pop()『eat』
s.pop()indexerror: pop from an empty deque
3、queue.lifoqueue
顧名思義,這個就是乙個棧。不過它是執行緒安全的,如果要在併發的環境下使用,那麼就可以選擇使用lifoqueue。
它入棧和出棧操作是使用put()和get(),其中get()在lifoqueue為空時會阻塞。
from queue import lifoqueues = lifoqueue()
s.put(『eat』)
s.put(『sleep』)
s.put(『code』)
s
s.get()『code』
s.get()『sleep』
s.get()『eat』
s.get()
0x01 佇列(queue)
佇列是一種fifo(先進先出)的資料結構。它有入隊(enqueue)、出隊(dequeue)兩種操作,而且也是常數時間的操作。
在python中可以使用哪些資料結構來實現乙個佇列呢?
1、list
list可以實現乙個佇列,但它的入隊、出隊操作就不是非常高效了。因為list是乙個動態列表,在佇列的頭部執行出隊操作時,會發生整個元素的移動。
q.pop(0)『1』
q.pop(0)『2』
q.pop(0)『three』
q.popleft()『eat』
q.popleft()『sleep』
q.popleft()『code』
q.popleft()indexerror: pop from an empty deque
3、queue.queue
同樣地,如果要在併發環境下使用佇列,那麼選擇執行緒安全的queue.queue。
與lifoqueue類似,入隊和出隊操作分別是put()和get()方法,get()在隊列為空時會一直阻塞直到有元素入隊。
from queue import queueq = queue()
q.put(『eat』)
q.put(『sleep』)
q.put(『code』)
q
q.get()『eat』
q.get()『sleep』
q.get()『code』
q.get_nowait()_queue.empty
q.put(『111』)q.get_nowait()
『111』
q.get()
4、multiprocessing.queue
多程序版本的佇列。如果要在多程序環境下使用佇列,那麼應該選擇multiprocessing.queue。
同樣地,它的入隊出隊操作分別是put()和get()。get()方法在隊列為空,會一直阻塞直到佇列不為空。
from multiprocessing import queueq = queue()
q.put(『eat』)
q.put(『sleep』)
q.put(『code』)
q
q.get()『eat』
q.get()『sleep』
q.get()『code』
q.get_nowait()_queue.empty
q.get()
0x02 優先順序佇列(priorityqueue)
乙個近乎排序的序列裡可以使用優先順序佇列這種資料結構,它能高效獲取最大或最小的元素。
在排程問題的場景中經常會用到優先順序佇列。它主要有獲取最大值或最小值的操作和入隊操作。
1、list
使用list可以實現乙個優先順序佇列,但它並不高效。因為當要獲取最值時需要排序,然後再獲取最值。一旦有新的元素加入,再次獲取最值時,又要重新排序。所以並推薦使用。
2、heapq
一般來說,優先順序佇列都是使用堆這種資料結構來實現。而heapq就是python標準庫中堆的實現。heapq預設情況下實現的是最小堆。
(1, 『eat』)
(2, 『code』)
(3, 『sleep』)
3、queue.priorityqueue
queue.priorityqueue內部封裝了heapq,不同的是它是執行緒安全的。在併發環境下應該選擇使用priorityqueue。
from queue import priorityqueueq = priorityqueue()
q.put((2, 『code』))
q.put((1, 『eat』))
q.put((3, 『sleep』))
while not q.empty():
next_item = q.get()
print(next_item)
(1, 『eat』)
(2, 『code』)
(3, 『sleep』)
0x03 總結一下
很多基礎的資料結構在python中已經實現了的,我們不應該重複造輪子,應該選擇這些資料結構來實現業務需求。
collections.deque是一種雙向鍊錶,在單執行緒的情況下,它可以用來實現stack和queue。而heapq模組可以幫我們實現高效的優先順序佇列。
如果要在多併發的情況下使用stack、queue和priorityqueue的話,那麼應該選用queue模組下類:
實現stack的queue.lifoqueue
實現queue的queue.queue或multiprocessing.queue
實現priorityqueue的queue.priorityqueue
以上這些類都有put()和get()方法,且get()會在棧/隊列為空時阻塞。
python基礎練習 資料結構第四天
python 中set與dict類似,也是一組key的集合,但不儲存value。由於key不能重複,所以,在set中,沒有重複的key。注意,key為不可變型別,即可雜湊的值。例子 112 num print type num num print type num 例子 113 basket set...
大話資料第四天
字尾表示式 中綴表示式轉字尾表示式 定義 佇列是允許在一端進行插入操作,而在另一端進行刪除操作的線性表。允許插入的叫隊尾,允許刪除的一端稱為對頭 迴圈佇列 假設乙個佇列有n個元素,則順序儲存的佇列序建立乙個大於n的陣列,並把佇列的所有元素儲存在陣列的前n個單元中,陣列下標為0的一端即是對頭。當佇列要...
學習資料結構的第四天 雙向鍊錶
建立輔助節點temp指向表頭,建立兩乙個節點temp2存放temp.next 遍歷鍊錶,若temp.next null,遍歷到最後 temp.next.no 新節點.no,可以新增,並且退出迴圈 temp.next.no 新節點.no,表示已經存在 新增節點,如果是temp.next null情況,...