priorityqueue(優先佇列)使用過程的坑
現在有乙個string型別的陣列,我們需要按照每個字串的長度按照從大到小對陣列進行排序。例如「leetcode」,「is」,「cool」,顯然,結果是「leetcode」「cool」「is」。
最簡潔的思路則是利用priorityqueue,並重寫comparator介面來完成排序。**如下:
string[
] arr = text.
split
(" ");
priorityqueue
pq =
newpriorityqueue
<
>
(new
comparator
()})
;int i =0;
for(string s: arr)
那麼問題的關鍵來了,如何取出佇列中的元素,正常的**應該是這樣的:
list
res =
newlinkedlist
<
>()
;while
(pq.
size()
>0)
通過這樣一段**呢,我們可以逐步將佇列中的每個元素取出,並最終得到我們想要的順序,但是我們突發奇想,如果利用foreach語句來取出元素會是什麼效果呢?既**如下:
for
(string s:pq)
我想恐怕很多人會認為,這兩個答案有什麼不一樣的呢,那麼不妨來看看編譯器給出的結果吧:
res:leetcode is cool
這個恐怕令人大吃一驚同樣的資料結構,僅僅是取出的方式不同,為什麼原本有序的結果彷彿就沒有排序過了一樣。
要說明這個問題,首先就要知道priorityqueue是有序的二叉堆(根據堆有序的概念,這意味著每個節點都必須必他的兩個子節點要大),但是呢,我們在實現的過程之中卻是利用陣列來進行的儲存,這個可以在priorityqueue的原始碼得以體現:
transient object[
] queue;
// non-private to simplify nested class access
那麼我們對問題裡的情況進行分析,當我們把leetcode is cool 三個字串全部輸入以後,按照堆有序的規則畫出二叉堆時候,是不是就應當leetcode作為堆頂,而is cool分別作為其子節點。由於陣列的第乙個代表堆頂,所以在儲存時,leetcode應該是陣列第乙個,而is 和cool分別是第二個第三個,所以在foreach按照順序去取出元素時,得出了剛才的結論。
。如果繼續新增元素,例如,but,由於but長度比堆頂is長,比cool短,則應該更新為cool的子節點,順序儲存結構應該是leetcode is cool but。
那麼為什麼正常poll的結果卻可以得出正確的結果呢,是因為priorityqueue在每次呼叫poll後,都重新對堆進行了有序化的操作,可以在poll的原始碼之中得到體現:
public e poll()
其中的siftdown則是這部分**。
從上面的經驗來看, priorityqueue在使用過程之中的序列化陣列並非有序的,所以要從priorityqueue之中正確取出元素,一定要使用poll方法逐次取出。
priority queue 優先佇列)
佇列 先輸入先輸出 優先佇列使用方法 標頭檔案 include using namespace std 宣告方法 1.普通方法 priority queueq 下劃線不可漏,預設從大到小輸出隊 2.結構體宣告方式 struct node int x,y frinend bool operator n...
優先佇列 priority queue
優先佇列 是一種抽象資料型別,行為有些像佇列,但是他不是先進先出型佇列 先出優先佇列的元素是佇列中優先順序最高的元素。就像 急診病人插隊 優先佇列的標頭檔案也是 用 priority queuepq 來宣告。這個pq是乙個越小的整數優先順序越低的優先佇列。出隊元素不是先進隊的元素,出隊的方法由que...
優先佇列 PriorityQueue
import queue q queue.priorityqueue q.put 1 新增元素 q.get 刪除元素 python的優先佇列基於最小堆實現。heap 堆 是乙個除了底層節點外的完全填滿的二叉樹,底層可以不完全,左到右填充節點。而最小堆意味著,任一非終端節點的資料值均不大於其左子節點和...