一、优先队列实现方法
应想到使用二叉查找树实现优先队列(线性表的思想被否决了,接下来该想到的也应该是树结构了吧),它可以使这两种操作的平均运行时间都是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; }