優先隊列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 + '\'' + '}'; } }
輸出結果: