Java集合框架源碼研讀-PriorityQueue

前面我們已經(jīng)介紹了好幾個Map了,今天我們來介紹一個更加簡單的數(shù)據(jù)結(jié)構(gòu),PriorityQueue.

從其名字中,我們就能看出,PriorityQueue首先是一個Queue,其中它的元素都是按照priority進行排序的.

那么如何實現(xiàn)一個PriorityQueue呢?

實際上有很多方法,數(shù)組,鏈表,堆都可以實現(xiàn).因為實際上我們可以看到,它不過就是一個按照priority進行排序的一個數(shù)據(jù)結(jié)構(gòu).

我們先來分析一下PriorityQueue需要具有的基本操作.

首先,由于它是一個Queue,就必然要求Queue的一些特性:

  • 不限容量
  • 先進先出
  • 只能從隊首讀取數(shù)據(jù),從隊尾插入數(shù)據(jù)

除此之外,由于其又增加了Priority的特性,這就要求其能夠?qū)ζ渲械臄?shù)據(jù)進行排序,按照優(yōu)先級進行服務(wù).

這種優(yōu)先級隊列的應(yīng)用場景很多,比如我們熟知的進程調(diào)度算法.

我們來分析一下使用數(shù)組,鏈表以及堆實現(xiàn)它的優(yōu)缺點.

幾種實現(xiàn)PriorityQueue的數(shù)據(jù)結(jié)構(gòu)

數(shù)組實現(xiàn)

數(shù)組的優(yōu)缺點都很明顯,優(yōu)點是能夠根據(jù)索引從任意位置訪問,進行數(shù)據(jù)存取,缺點是容量有限,再就是插入或者刪除數(shù)據(jù)時,如果給定位置有數(shù)據(jù),那么需要進行數(shù)據(jù)的移動,代價很大.

實際上,從根本上來說的話,PriorityQueue的實現(xiàn),還就是一個數(shù)組,只不過是一種特殊形式的數(shù)組.

鏈表實現(xiàn)

鏈表的優(yōu)點是,存取數(shù)據(jù),刪除數(shù)據(jù)等很方便,以及容量無限,缺點是,遍歷起來很麻煩,時間復(fù)雜度為O(n).而鏈表中基本所有操作的前提都是先通過遍歷找到對應(yīng)的元素.

所以,其所有操作的時間復(fù)雜度,如果算上定位對應(yīng)元素的時間復(fù)雜度,實際上都是O(n)的.

堆實現(xiàn)

堆又分為最大堆和最小堆.

實際上,堆的內(nèi)部數(shù)據(jù)結(jié)構(gòu)還是一個數(shù)組,只不過是一個特殊的數(shù)組,其邏輯結(jié)構(gòu)為一棵樹,一棵完全二叉樹.上面我們所說的數(shù)組就是這棵完全二叉樹的層序遍歷的結(jié)果.

堆跟完全二叉樹的區(qū)別在于其性質(zhì),其性質(zhì)表明,在最大堆中,父節(jié)點是其子樹的最大節(jié)點,在最小堆中,父節(jié)點是其子樹的最小節(jié)點.

堆的這些性質(zhì),保證了插入和刪除操作的時間復(fù)雜度為O(logn),查找操作的時間復(fù)雜度為O(1).

PriorityQueue的實現(xiàn)

具體的實現(xiàn)方式,上面我們也已經(jīng)說過了,實際上就是一個堆,一個二叉堆.

那么為什么采用二叉堆的這種結(jié)構(gòu)呢?因為上面我們已經(jīng)說了,二叉堆的性能比較好.

PriorityQueue中的具體的各種方法,我們這里就不介紹了,就是跟Queue相關(guān)的那些操作.其各種操作,無非就是對這個堆的進行的各種操作.

需要注意的地方

  • PriorityQueue不允許NULL
  • PriorityQueue不是線程安全的,它是Fail-Fast的.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容