目录
1.PriorityQueue的特性
2.PriorityQueue接口介绍
2.1PriorityQueue的造方式
2.2插入/删除/获取优先级最高的元素
3.top-k问题
import java . util . PriorityQueue ;
public static void main(String[] args) {
PriorityQueue priorityQueue = new PriorityQueue<>();
priorityQueue.offer(new Student(18,"wh"));
priorityQueue.offer(new Student(18,"zhangshan"));
}
public class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) {
PriorityQueue priorityQueue = new PriorityQueue<>();
priorityQueue.offer(new Student(18,"wh"));
}
因为只添加一个,不用比较。
(3)不能插入null对象,否则会抛出NullPointerException
(4)没有容量限制,可以插入任意多个元素,其内部可以自动扩容
(5)PriorityQueue默认情况下是小堆---即每次获取到的元素都是最小的元素,如果需要大堆需要用户提供比较器
举例:
public static void main(String[] args) {
PriorityQueue priorityQueue = new PriorityQueue<>();
priorityQueue.offer(100);
priorityQueue.offer(2);
priorityQueue.offer(-2);
System.out.println(priorityQueue.poll());
System.out.println(priorityQueue.poll());
System.out.println(priorityQueue.poll());
}
运行结果:
如果需要大堆需要用户提供比较器
举例:
class IntCmp implements Comparator{
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
}
public class TestPriorityQueue {
public static void main(String[] args) {
PriorityQueue p = new PriorityQueue<>(new IntCmp());
p.offer(4);
p.offer(3);
p.offer(2);
p.offer(1);
p.offer(5);
System.out.println(p.peek());
}
}
运行结果:5
private static final int DEFAULT_INITIAL_CAPACITY = 11;
public PriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
}
故创建PriorityQueue()时数组的默认容量是11;
(2)PriorityQueue(Collection extends E> c)的举例使用
ArrayList
list = new ArrayList<>();
list.add(4);
list.add(3);
list.add(2);
list.add(1);// 用ArrayList对象来构造一个优先级队列的对象
// q中已经包含了三个元素
PriorityQueueq = new PriorityQueue<>(list);
System.out.println(q.size());
System.out.println(q.peek());
(1)offer底层代码展示
private static final long serialVersionUID = -7720805057305804111L;
private static final int DEFAULT_INITIAL_CAPACITY = 11;
transient Object[] queue;
private int size = 0;
private final Comparator super E> comparator;
offer:
public boolean offer(E e) {
if (e == null)
throw new NullPointerException();
modCount++;
int i = size;
if (i >= queue.length)
grow(i + 1);
size = i + 1;
if (i == 0)
queue[0] = e;
else
siftUp(i, e);
return true;
}
siftUp:
private void siftUp(int k, E x) {
if (comparator != null)
siftUpUsingComparator(k, x);
else
siftUpComparable(k, x);
}
siftUpUsingComparator:
private void siftUpUsingComparator(int k, E x) {
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (comparator.compare(x, (E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = x;
}
siftUpComparable:
private void siftUpComparable(int k, E x) {
Comparable super E> key = (Comparable super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}
(2)PriorityQueue的扩容方式:
private void grow(int minCapacity) {
int oldCapacity = queue.length;
// Double size if small; else grow by 50%
int newCapacity = oldCapacity + ((oldCapacity < 64) ?
(oldCapacity + 2) :
(oldCapacity >> 1));
// overflow-conscious code
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
queue = Arrays.copyOf(queue, newCapacity);
}
如果容量小于 64 时,是按照 oldCapacity 的 2 倍方式扩容的如果容量大于等于 64 ,是按照 oldCapacity 的 1.5 倍方式扩容的如果容量超过 MAX_ARRAY_SIZE ,按照 MAX_ARRAY_SIZE 来进行扩容
代码:
class Solution {
public int[] smallestK(int[] arr, int k) {
int[] ret = new int[k];
if (arr==null||k<=0){
return ret;
}
imp imp = new imp();
PriorityQueue priorityQueue = new PriorityQueue<>(imp);
for (int i = 0; i < k; i++) {
priorityQueue.offer(arr[i]);
}
for (int i = k; i < arr.length; i++) {
int top=priorityQueue.peek();
if(top>arr[i]){
priorityQueue.poll();
priorityQueue.offer(arr[i]);
}
}
for (int i = 0; i < k; i++) {
ret[i]=priorityQueue.poll();
}
return ret;
}
}
class imp implements Comparator {
public int compare(Integer o1,Integer o2) {
return o2-o1;
}
}
解析:
将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞