优先队列priorityQueue是Queue接口的实现,可以对其中元素进行排序,可以放基本的包装类型或自定义的类,对于基本类型的包装类,优先队列中元素的默认排列顺序是升序,但是对于自定义类来说,需要自定义比较类
priorityQueue的内部实现
PriorityQueue对元素采用的是堆排序,头是按指定排序方式的最小元素。堆排序只能保证根是最大(最小),整个堆并不是有序的。
方法iterator()中提供的迭代器可能只是对整个数组的依次遍历。也就只能保证数组的第一个元素是最小的
PriorityQueue的iterator()不保证以任何特定顺序遍历队列元素。若想按特定顺序遍历,先将队列转成数组,然后排序遍历。Arrays.sort(pq.toArray())
常用方法:
peek()//返回队首元素
poll()//返回队首元素,队首元素出队列
add()//添加元素
size()//返回队列元素个数
isEmpty()//判断队列是否为空,为空返回true,不空返回false
队列保存的是基本数据类型的包装类:
Top k 问题求前k小
class Main {
public static void main(String[] args) {
int[] array = {9,8,7,6,5,4,3,2,1};
System.out.println(Solution(array,4));
}
public static ArrayList<Integer> Solution(int[] array, int k) {
ArrayList<Integer> result = new ArrayList<>();
int length = array.length;
if (k > length || k <= 0) {
return result;
}
PriorityQueue<Integer> maxheap = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
for (int i = 0; i < length; i++) {
if (maxheap.size() != k){
maxheap.offer(array[i]);
}
else if(array[i] < maxheap.peek()){
maxheap.poll();
maxheap.offer(array[i]);
}
}
for(Integer num : maxheap){
result.add(num);
}
return result;
}
}
队列保存的是自定义类
第一种写法(在priorityQueue构造时,new Comparator)
class Main {
public static void main(String[] args) {
PriorityQueue<person> priorityQueue = new PriorityQueue<person>(10, new Comparator<person>() {
@Override
public int compare(person o1, person o2) {
if (o1.getAge() != o2.getAge()){
return o1.getAge() - o2.getAge();
}
else if(o1.getAge() == o2.getAge() && o1.getTall()!=o2.getTall()){
return o1.getTall() - o2.getTall();
}
else {
return o2.getName().length() - o1.getName().length();
}
}
});
priorityQueue.add(new person(11,160,"Nick"));
priorityQueue.add(new person(16,172,"John"));
priorityQueue.add(new person(18,180,"Mike"));
priorityQueue.add(new person(22,183,"Jordan"));
priorityQueue.add(new person(16,172,"Alice"));
person p;
while (!priorityQueue.isEmpty()){
p = priorityQueue.poll();
System.out.println(p.toString());
}
}
}
class person{
private int age;
private int tall;
private String name;
public person(int age, int tall, String name) {
this.age = age;
this.tall = tall;
this.name = name;
}
public int getAge() {
return age;
}
public int getTall() {
return tall;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "person{" +
"age=" + age +
", tall=" + tall +
", name='" + name + '\'' +
'}';
}
}
第二种写法,构造PriorityQueue时传入Comparator
class MyQueue{
public static Comparator<person> cperson = new Comparator<person>() {
@Override
public int compare(person o1, person o2) {
if (o1.getAge() != o2.getAge()){
return o1.getAge() - o2.getAge();
}
else if(o1.getAge() == o2.getAge() && o1.getTall()!=o2.getTall()){
return o1.getTall() - o2.getTall();
}
else {
return o1.getName().length() - o2.getName().length();
}
}
};
public static void main(String[] args) {
Queue<person> priorityQueue = new PriorityQueue<>(100,cperson);
priorityQueue.add(new person(11,160,"Nick"));
priorityQueue.add(new person(16,172,"John"));
priorityQueue.add(new person(18,180,"Mike"));
priorityQueue.add(new person(22,183,"Jordan"));
person p;
while (!priorityQueue.isEmpty()){
p = priorityQueue.poll();
System.out.println(p.toString());
}
}
}
class person{
private int age;
private int tall;
private String name;
public person(int age, int tall, String name) {
this.age = age;
this.tall = tall;
this.name = name;
}
public int getAge() {
return age;
}
public int getTall() {
return tall;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "person{" +
"age=" + age +
", tall=" + tall +
", name='" + name + '\'' +
'}';
}
}
输出结果:
优先队列priorityQueue是Queue接口的实现,可以对其中元素进行排序,可以放基本的包装类型或自定义的类,对于基本类型的包装类,优先队列中元素的默认排列顺序是升序,但是对于自定义类来说,需要自定义比较类
priorityQueue的内部实现
PriorityQueue对元素采用的是堆排序,头是按指定排序方式的最小元素。堆排序只能保证根是最大(最小),整个堆并不是有序的。
方法iterator()中提供的迭代器可能只是对整个数组的依次遍历。也就只能保证数组的第一个元素是最小的
PriorityQueue的iterator()不保证以任何特定顺序遍历队列元素。若想按特定顺序遍历,先将队列转成数组,然后排序遍历。Arrays.sort(pq.toArray())