Java优先级队列源码分析

先导课程:二叉堆学习

优先级队列

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如下:

Java优先级队列源码分析_第1张图片

3.1offer方法源码分析

我们来看下如何给优先级队列添加元素

Java优先级队列源码分析_第2张图片

可以看到里面最重要的方法就是我们堆操作的siftUp,在点进去看就是和我们一样的堆操作的逻辑了,jdk的优先级队列底层就是二叉堆

3.2 批量建堆源码

可以看到批量建堆的源码跟我们一样采用的也是自下而上的下滤

的方法就是我们堆操作的siftUp,在点进去看就是和我们一样的堆操作的逻辑了,jdk的优先级队列底层就是二叉堆

3.2 批量建堆源码

可以看到批量建堆的源码跟我们一样采用的也是自下而上的下滤

Java优先级队列源码分析_第3张图片

你可能感兴趣的:(数据结构,java,开发语言,优先级队列)