Java算法竞赛常用类:PriorityQueue(优先队列)
初始化
PriorityQueue()// 使用默认的初始容量(11)创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。
PriorityQueue Q = new PriorityQueue<>(); // 初始化
常用函数
add(E e)// 将指定的元素插入此优先级队列。
clear()// 清空
contains(Object o) // 如果包含指定元素返回 true
iterator()// 返回在此队列中的元素上进行迭代的迭代器。
offer(E e) // 将指定元素插入此优先队列
peek() // 获取第一个元素,及最小或最大元素
poll() // 获取并移除第一个
remove(Object o) // 移除指定元素
size() // 返回元素个数
实现大根堆的两种方式
因为 java 中的优先队列默认是小根堆,要实现大根堆可以用以下两种方法:
使用自定义比较器
将所有数据变为之前自身的负数之后在插入, 因为添加个负号就相当于是逆序了嘛。1 <2 < 3 取负之后变为 -1> - 2 > - 3
实例
public static void main(String[] args){
Scanner in = new Scanner(new InputStreamReader(System.in));
PriorityQueue Q = new PriorityQueue<>();
int a;
for(int i = 0; i < 10; i++){
a = in.nextInt();
Q.add(a);
System.out.print(Q.peek()+" ");// 输出当前队列的最小元素
}
}
输入: 1 -1 -2 -3 10 -4 -5 -6 -7 -8
输出: 1 -1 -2 -3 -3 -4 -5 -6 -7 -8
这里有一个地方要注意,Java的优先队列是小顶堆,并且堆的性质决定了,只能保证堆顶是最小/大的,所以迭代器遍历没有意义,只能选择不断poll出堆顶元素来获得最小元素:
package com.jiading.noi;
/*
* 2405:Avoid The Lakes
* http://noi.openjudge.cn/ch0308/2405/
*/
import java.util.Iterator;
import java.util.PriorityQueue;
public class Problem19 {
public static void main(String[] args) {
PriorityQueueheap=new PriorityQueue<>();
heap.add(5);
heap.add(10);
heap.add(1);
System.out.println("使用迭代器");
Iterator iterator=heap.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("直接访问堆");
while(!heap.isEmpty()) {
System.out.println(heap.poll());
}
}
}
输出是:
使用迭代器
1
10
5
直接访问堆
1
5
10