数据结构(Java)—— 优先级队列(堆)

1. 概念

    优先级队列是一种抽象数据类型(ADT),它允许队列中维护的元素按优先级排序,优先级最高的元素会优先被处理。

2. 使用

2.1 优先级队列的构造

构造器
功能介绍
PriorityQueue()
创建一个空的优先级队列,默认容量是11
PriorityQueue(int  initialCapacity)
创建一个初始容量为 initialCapacity 的优先级队列,注意:
initialCapacity不能小于 1 ,否则会抛 IllegalArgumentException 异常
PriorityQueue(Collection<?
extends E> c)
用一个集合来创建优先级队列

代码示例:

      public static void main(String[] args) {
        // 创建一个空的优先级队列,底层默认容量是11
        PriorityQueue<Integer> q1 = new PriorityQueue<>();
        // 创建一个空的优先级队列,底层的容量为initialCapacity
        PriorityQueue<Integer> q2 = new PriorityQueue<>(100);
        ArrayList<Integer> list = new ArrayList<>();
        list.add(4);
        list.add(3);
        list.add(2);
        list.add(1);
        // 用ArrayList对象来构造一个优先级队列的对象
        // q3中已经包含了三个元素
        PriorityQueue<Integer> q3 = new PriorityQueue<>(list);
        System.out.println(q3.size());
        System.out.println(q3.peek());
    }

运行结果如下:

注意:默认情况下, PriorityQueue 队列是小堆,如果需要大堆需要用户提供比较器

2.2 方法

函数名
功能介绍
boolean offer(E e)
插入元素 e ,插入成功返回 true ,如果 e 对象为空,抛出 NullPointerException 异常,注意:空间不够时候会进行扩容
### Java 优先级队列 PriorityQueue 的使用与实现 #### 创建 PriorityQueue 对象 在 Java 中,`PriorityQueue` 是一种特殊的队列,它能够根据元素的自然顺序或者通过指定比较器定义的顺序自动排列元素。创建 `PriorityQueue` 对象可以通过无参构造函数完成[^1]。 ```java PriorityQueue<String> priorityQueue = new PriorityQueue<>(); ``` 上述代码片段展示了如何实例化一个默认的小根形式的 `PriorityQueue`,其中字符串类型的元素会依据其字典序进行排序。 #### 数据结构基础—— `PriorityQueue` 的底层实现依赖于 **** 这种数据结构[^2]。具体而言,默认情况下,`PriorityQueue` 使用的是小根(Min Heap),即父节点总是小于等于子节点;如果需要大根,则可以自定义比较器来改变这种行为。 当向 `PriorityQueue` 插入新元素时,这些元素会被放置到合适的位置以维持属性不变。同样,在移除元素时,也是从顶取出最高优先级的元素并重新调整剩余部分保持特性。 #### 自然顺序 vs 定制比较逻辑 除了依靠对象自身的可比较接口 (`Comparable`) 来决定次序外,还可以传入定制化的 `Comparator` 实现更灵活的控制方式[^3]: ```java // 默认按升序存储整数 PriorityQueue<Integer> intPQAscend = new PriorityQueue<>(); // 利用 Comparator 构建降序排列的 Integer 队列 PriorityQueue<Integer> intPQDescend = new PriorityQueue<>(Collections.reverseOrder()); ``` 这里分别演示了两种不同方向上的数值型优先级管理方法:前者遵循常规从小到大的原则;后者则借助工具类反转原有关系从而达成相反效果。 #### 主要操作方法概览 以下是几个常用的 API 方法用于操控 `PriorityQueue` 实例: - 添加单个项至队尾:`add(E e)` 或者 `offer(E e)` - 获取但不删除头部(最大/最小值):`peek()` - 移除头结点的同时返回它的值:`poll()` 需要注意的一点是由于内部采用了动态数组作为容器载体,因此容量是可以扩展增长的. 最后附上一段综合运用以上知识点的例子程序供参考学习: ```java import java.util.PriorityQueue; import java.util.Comparator; public class Main { public static void main(String[] args){ // 初始化一个基于 String 类型的大顶 PriorityQueue<String> pqCustomized = new PriorityQueue<>( new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); // 反转标准字符序列得到逆序结果 } } ); pqCustomized.add("Banana"); pqCustomized.offer("Apple"); pqCustomized.offer("Orange"); System.out.println(pqCustomized.peek()); // 输出 Orange (首字母 O 大写排最前) while(!pqCustomized.isEmpty()){ System.out.print(pqCustomized.poll()+" "); /*依次打印 Orange Banana Apple */ } } } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值