Java优先级队列源码分析

文章介绍了如何使用二叉堆实现优先级队列,遵循先进先出(FIFO)原则,但按优先级出队。提供了基本接口如入队、出队、获取头元素等。接着展示了用Java实现的PriorityQueue类,以及其内部使用二叉堆的细节。文章还探讨了JDK中PriorityQueue的offer方法和批量建堆的源码,证实其底层同样基于二叉堆并采用自下而上的下滤策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先导课程:二叉堆学习

优先级队列

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

image-20230613212055889

3.1offer方法源码分析

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

image-20230613212250517

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

3.2 批量建堆源码

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

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

3.2 批量建堆源码

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

image-20230613214737806

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值