优先级队列——PriorityQueue
在大量数据中找前4个最大的数:
1)首先将待排序的前4个元素进行建堆(小堆)。
2)遍历剩下的元素,如果比堆顶元素小,那么就将堆顶元素出堆,当前元素入堆。
注意:
- 如果找最小的4个元素,则需要建立大堆。
- PriorityQueue默认建的是小堆,要想改变调整顺序,调整为大堆,那么就需要传入一个比较器。
java代码实现:
import java.util.PriorityQueue;
public static Integer[] findKNum(int[] array,int k) {
//1、建立大小为K的堆(小堆)
PriorityQueue<Integer> minHeap = new PriorityQueue<>
(k, new Comparator<Integer>() {
//调整的时候,比较
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);//默认是小堆
//return o2.compareTo(o1);//大堆
}
});
for(int i = 0; i < array.length; i++) {
if(minHeap.size() < k) {
minHeap.add(array[i]);
}else {
Integer top = minHeap.peek();
if(top != null && top > array[i]) {
minHeap.poll();
minHeap.add(array[i]);
}
}
}
//返回一个Integer[] 类型的数组
Integer[] integers = new Integer[k];
for (int i = 0; i < k; i++) {
Integer top = minHeap.peek();
integers[i] = top;
minHeap.poll();
}
return integers;
}
public static void main(String[] args) {
int[] array = {12,4 ,6 ,17, 9, 51 ,21, 10, 45 ,31};
Integer[] ret = findKNum(array,4);
System.out.println(Arrays.toString(ret));
}
针对这一块:
这比较的部分,是在堆的poll和add后调整用的。
//1、建立大小为K的堆(小堆)
PriorityQueue<Integer> minHeap = new PriorityQueue<>
(k, new Comparator<Integer>() {
//调整的时候,比较
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);//默认是小堆
//return o2.compareTo(o1);//大堆
}
});
这是compareTo的底层:
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
o1代表当前对象,o2代表待比较对象。
- return o1.compareTo(o2);//表示调整为小堆 o1-o2=-1,即o1<o2,向上调整。
- return o2.compareTo(o1);//表示调整为大堆 o2-o1=-1,即o2<o1, 向上调整。