注意:這裏的優先級隊列不是數據結構中的概念,而是java中的集合類。
注意:建議先把我博客裏的堆,比較器這兩篇文章看一哈
優先級隊列的定義
- 優先級隊列是邏輯結構是小根堆,存儲結構是動態數組(到達上限,容量自動加一)的集合類。
優先級隊列的特點
- 優先級隊列裏的元素必須有優先級!!!優先級是前後排序的“規則”,也就是說插入隊列的類必須實現內部比較器或擁有外部比較器(在構造函數中當參數)!!!!
- 優先級隊列的擁有小根堆的所有特性。
- 優先級隊列不是線程安全的。
- 優先級隊列不允許使用null元素。
- 優先級隊列本身並一個有序(從a[0]-a[n]全部升序)序列,只有當你把元素一個個取出的時候,這些取出的元素所排成的序列纔是有序序列。原因很簡單,優先級隊列是一個小根堆,也就是隻能保證根節點(a[0])是最小的,其餘元素的順序不能保證(當然,其他元素必須遵守小根堆的特性),當我們取出元素(poll)時,我們只能取出根節點的元素,然後把堆的最後一個元素剪切到根節點(這種取出方式是底層算法規定的,充分利用了堆的特性),然後對所有剩餘元素進行建堆,建堆之後根節點元素還是最小的(初始堆中的第二小)。由此特點,我們可以引出另外兩個知識點:①優先級隊列的迭代器遍歷出來的數組是沒有排序的,只是個小根堆。②如果我們想得到有序的堆,需要把堆先轉爲數組,然後arrays.sort(queue.toarray),arrays.sort(queue.toarray,comparator對象)或者其他sort方法。
- 優先級隊列(堆)中的插入就只能插到最後,也就是說添加和插入一個意思;刪除也只能刪第一個。
- 注:每個元素的優先級根據問題的要求而定。當從優先級隊列中取出一個元素後,可能出現多個元素具有相同的優先權。在這種情況下,把這些具有相同優先權的元素視爲一個先來先服務的隊列,按他們的入隊順序進行先後處理。
常用方法:
添加(插入):
public boolean add(E e)
查看(只返回根節點元素,不刪除):
public E peek()
取出(返回根節點元素,會刪除源數據):
public E poll()
刪除(如果有多個相同元素,只會刪除第一個):
public boolean remove(Object o)
還有就是一些collection類通有的方法,不多說了
記住!!!所有會破壞堆的特性的方法(比如插入刪除等)的源碼裏最後都會加一個建堆方法(siftUp(i, e),也可以說交換方法,調整方法),使隊列保持堆的特性
感謝幾位大佬,想了解更多源碼,例子,實例圖的可以去看看:
https://www.cnblogs.com/demingblog/p/6485193.html
https://www.cnblogs.com/CarpenterLee/p/5488070.html
https://blog.csdn.net/u013309870/article/details/71189189
https://blog.csdn.net/cainv89/article/details/51588920