先导课程:二叉堆学习
优先级队列
1. Priority Queue
优先级队列(Priority Queue)也是队列
- 普通队列按照
FIFO
原则,也就是先进先出- 优先级队列按照
优先级高低
进行出队,比如将优先级最高
的元素作为队头
优先出队
基本接口和队列保持一样
int size(); // 元素的数量
boolean isEmpty(); // 是否为空
void enQueue(E element); // 入队
E deQueue(); // 出队
E front(); // 获取队列的头元素
void clear(); // 清空
2. 使用二叉堆实现优先级队列
实现比较简单
/**
* 使用堆来实现优先级队列
*
* @author eureka
* @since 2023/6/13 12:40
*/
public class PriorityQueue<E> implements Queue<E> {
private final BinaryHeap<E> binaryHeap;
public PriorityQueue() {
binaryHeap = new BinaryHeap<>();
}
public PriorityQueue(Comparator<E> comparator) {
binaryHeap = new BinaryHeap<>(comparator);
}
@Override
public int size() {
return binaryHeap.size();
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public void enQueue(E element) {
binaryHeap.add(element);
}
@Override
public E deQueue() {
return binaryHeap.remove();
}
@Override
public E front() {
return binaryHeap.get();
}
@Override
public void clear() {
binaryHeap.clear();
}
}
测试
@Test
public void test01() {
PriorityQueue<Person> priorityQueue = new PriorityQueue<>((p1, p2) -> p1.age - p2.age);
priorityQueue.enQueue(new Person(22, "张三"));
priorityQueue.enQueue(new Person(18, "李四"));
priorityQueue.enQueue(new Person(25, "王五"));
while (!priorityQueue.isEmpty()) {
System.out.println(priorityQueue.deQueue());
}
}
// 输出
Person{age=25, name='王五'}
Person{age=22, name='张三'}
Person{age=18, name='李四'}
3. jdk优先级队列源码分析
在java.util
包下也有一个优先级队列PriorityQueue
,API如下:
3.1offer方法源码分析
我们来看下如何给优先级队列添加元素
可以看到里面最重要的方法就是我们堆操作的siftUp
,在点进去看就是和我们一样的堆操作的逻辑了,jdk的优先级队列底层就是二叉堆
3.2 批量建堆源码
可以看到批量建堆的源码跟我们一样采用的也是自下而上的下滤
的方法就是我们堆操作的siftUp
,在点进去看就是和我们一样的堆操作的逻辑了,jdk的优先级队列底层就是二叉堆
3.2 批量建堆源码
可以看到批量建堆的源码跟我们一样采用的也是自下而上的下滤