在做一道算法時需要使用大頂堆,所以查了一下記錄。
使用PriorityQueue實現大頂堆
PriorityQueue默認是一個小頂堆,然而可以通過傳入自定義的Comparator函數來實現大頂堆。如下代碼實現了一個初始大小為11的大頂堆。這里只是簡單的傳入一個自定義的Comparator函數,就可以實現大頂堆了。
-
private
static
final
int DEFAULT_INITIAL_CAPACITY =
11;
-
PriorityQueue<Integer> maxHeap=
new PriorityQueue<Integer>(DEFAULT_INITIAL_CAPACITY,
new Comparator<Integer>() {
-
@Override
-
public int compare(Integer o1, Integer o2) {
-
return o2-o1;
-
}
-
});
PriorityQueue的邏輯結構是一棵完全二叉樹,存儲結構其實是一個數組。邏輯結構層次遍歷的結果剛好是一個數組。
例子:輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
可以使用大頂堆保存,比堆中的數小就進堆。
-
import java.util.ArrayList;
-
import java.util.PriorityQueue;
-
import java.util.Comparator;
-
public
class Solution {
-
public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
-
ArrayList<Integer> result =
new ArrayList<Integer>();
-
int length = input.length;
-
if(k > length || k ==
0){
-
return result;
-
}
-
PriorityQueue<Integer> maxHeap =
new PriorityQueue<Integer>(k,
new Comparator<Integer>() {
-
-
@Override
-
public int compare(Integer o1, Integer o2) {
-
return o2.compareTo(o1);
-
}
-
});
-
for (
int i =
0; i < length; i++) {
-
if (maxHeap.size() != k) {
-
maxHeap.offer(input[i]);
-
}
else
if (maxHeap.peek() > input[i]) {
-
Integer temp = maxHeap.poll();
-
temp =
null;
-
maxHeap.offer(input[i]);
-
}
-
}
-
for (Integer integer : maxHeap) {
-
result.add(integer);
-
}
-
return result;
-
}
-
}
補充介紹其offer和poll方法:
①優先隊列中不能存放空元素。
②壓入元素后如果數組的大小不夠會進行擴充,上面的queue其實就是一個默認初始值為11的數組(也可以賦初始值)。
poll 方法每次從 PriorityQueue 的頭部刪除一個節點,也就是從小頂堆的堆頂刪除一個節點,而remove()不僅可以刪除頭節點而且還可以用 remove(Object o) 來刪除堆中的與給定對象相同的最先出現的對象。
具體的源碼解讀,參考
轉載自:https://blog.csdn.net/weixin_30363263/article/details/80862578