Java数据结构之优先级队列(PriorityQueue)
提示:以下是本篇文章正文内容,Java系列学习将会持续更新
一、基本概念
看似是队列,底层是基于堆实现的。按照元素间的优先级大小,进行动态的出入队。
二、实现优先级队列
import myQueue.Queue;
import myheap.MaxHeap;
/**
* 基于最大堆实现的优先级队列
*/
public class PriorityQueue implements Queue<Integer> {
private MaxHeap heap;
//构造方法中创建一个最大堆对象
public PriorityQueue() {
heap = new MaxHeap();
}
//入队
@Override
public void offer(Integer val) {
heap.add(val);
}
//出队
@Override
public Integer poll() {
return heap.extractMax();
}
//返回队首元素
@Override
public Integer peek() {
return heap.peekMax();
}
//判断队列是否为空
@Override
public boolean isEmpty() {
return heap.isEmpty();
}
}
三、java.util.PriorityQueue
// JDK下的优先级队列是基于最小堆实现的
Queue<Integer> queue1 = new PriorityQueue<>();
// 元素操作
queue1.offer(1); // 入队
queue1.poll(); // 出队
queue1.peek(); // 返回队首元素(最小值)
// 改造:如果想使用基于最大堆的优先级队列可以这样改
Queue<Integer> queue2 = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
四、TopK问题
优先级队列的应用场景:
最小或最大的k个元素 =》都是优先级队列 (堆的应用) 找最小的k个数,就构造最大堆。 找最大的k个数,就构造最小堆。 原因: 当你需要找k个较小的数时,你的最大堆顶部一定是堆中最大的元素。当遍历完所有元素时,堆顶的元素相比其它元素已经算是较小的元素了,那么堆中的其它元素一定更小。这样就有效地筛选出k个小值了。
leetCode题:
面试题17.14.最小K个数
class Solution {
public int[] smallestK(int[] arr, int k) {
if(arr.length == 0 || k == 0) {
return new int[0];
}
int[] ret = new int[k];
Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for(int i = 0; i < arr.length; i ++) {
if(queue.size() < k){
queue.offer(arr[i]);
} else if(arr[i] < queue.peek()){
queue.poll();
queue.offer(arr[i]);
}
}
// 此时队列中存着的就是最小的k个数
for(int i = ret.length - 1; i >= 0; i --){
ret[i] = queue.poll();
}
return ret;
}
}
总结: 提示:这里对文章进行总结: 以上就是今天的学习内容,本文是Java数据结构的学习,认识了优先级队列,如何自己实现,JDK下的优先级队列用法,以及在TopK问题中的应用。之后的学习内容将持续更新!!!
