資料結構--用堆實現優先佇列
阿新 • • 發佈:2019-02-01
一、優先佇列實現方法
應想到使用二叉查詢樹實現優先佇列(線性表的思想被否決了,接下來該想到的也應該是樹結構了吧),它可以使這兩種操作的平均執行時間都是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;
}