Java优先队列的用法
优先队列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 + '\'' + '}'; } }
输出结果: