一、優先隊列實現方法
應想到使用二叉查找樹實現優先隊列(線性表的思想被否決了,接下來該想到的也應該是樹結構了吧),它可以使這兩種操作的平均運行時間都是O(logN)。但是使用二叉查找樹會存在兩個問題
1:根節點的選擇。
2:使用指針的必要性。(我們不需要那麼“精確”的排序)
所以我們使用一種名爲“二叉堆”的工具,它具有二叉查找樹的部分思想,但我們將用數組去實現它(你也可以認爲就是用數組實現了個二叉查找樹)
二、實現heap類public class Heap<E extends Comparable<E>> {
private ArrayList<E> list = new ArrayList<>();
public Heap(){}
public Heap(E[] objects){
for (E object:objects) {
add(object);
}
}
public void add(E newObject){
list.add(newObject);
int currentIndex = list.size()-1;
while (currentIndex>0){
int parentIndex = (currentIndex-1)/2;
if(list.get(currentIndex).compareTo(list.get(parentIndex)) > 0){
E temp = list.get(currentIndex);
list.set(currentIndex, list.get(parentIndex));
list.set(parentIndex, temp);
}
else
break;
currentIndex = parentIndex;
}
}
public E remove(){
if(list.size() == 0) return null;
E removedObject = list.get(0);
list.set(0, list.get(list.size()-1));
list.remove(list.size()-1);
int currentIndex = 0;
while (currentIndex<list.size()){
int rightChildIndex = currentIndex*2+2;
int leftChildIndex = currentIndex*2+1;
if (leftChildIndex >= list.size()) break;
int maxIndex = leftChildIndex;
if(rightChildIndex < list.size()){
if(list.get(maxIndex).compareTo(list.get(rightChildIndex)) < 0){
maxIndex = rightChildIndex;
}
}
if(list.get(currentIndex).compareTo(list.get(maxIndex)) < 0){
E temp = list.get(maxIndex);
list.set(maxIndex, list.get(currentIndex));
list.set(currentIndex, temp);
currentIndex = maxIndex;
}
else break;
}
return removedObject;
}
public int getSize(){
return list.size();
}
}
二、實現PriorityQueue類
public class MyPriorityQueue<E extends Comparable<E>> {
private Heap<E> heap = new Heap<>();
public void enqueue(E newObject){
heap.add(newObject);
}
public E dequeue(){
return heap.remove();
}
public int getSize() {
return heap.getSize();
}
}
三、實現測試類
public class TestPriorityQueue { public static void main(String[] args){ Patient p1 = new Patient("Tom", 1); Patient p2 = new Patient("Jack", 8); Patient p3 = new Patient("Smith", 3); Patient p4 = new Patient("John", 5); MyPriorityQueue priorityQueue = new MyPriorityQueue(); priorityQueue.enqueue(p1); priorityQueue.enqueue(p2); priorityQueue.enqueue(p3); priorityQueue.enqueue(p4); while (priorityQueue.getSize() > 0){ System.out.println(priorityQueue.dequeue()); } } static class Patient implements Comparable<Patient>{ private String name; private int priority; public Patient(String name, int priority){ this.name = name; this.priority = priority; } @Override public int compareTo(Patient o) { return o.priority - this.priority; } @Override public String toString() { return "Patient{" + "name='" + name + '\'' + ", priority=" + priority + '}'; } } }
四、總結
父結點:(i-1)/2
左子節點:2 * i +1
右子節點:2 * i +2
實現Comparable<E>接口再重寫compareTo方法可以自定義比較器
static class Patient implements Comparable<Patient>
@Override
public int compareTo(Patient o) {
return o.priority - this.priority;
}