/** * Priority Queue implementation using heaps. This implementation can do either min or max, which is * set at initialization. It is superior to the ArrayList based implementation in that both * add and remove at O(log n). On there other hand, the heap is size limited. * * @param the key * @param the value * * For methods that exactly follow the interface, see the documentation in the interface. * * @author gtowell * Created APRIL 6, 2020 */ @SuppressWarnings("unchecked") public class PriorityQHeap, V> implements PriorityQInterface { /** * An inner class to keep key/value pair together. */ protected class Entry,W> { /** Hold the key */ final L theK; /** Hold the value*/ final W theV; /** * Create an Entry instance * @param kk the key * @param vv the value */ public Entry(L kk, W vv) { theK = kk; theV = vv; } /** * A little utility to do comparisons. Takes advantage of L being defined to be Comparable, * so all this really does is to wrap the comparable with something to flip signs for * Min heap vs max heap. * @param e2 the item to be compared. * @return -1, or or 1 */ private int doCompare(Entry e2) { switch (order) { case MIN: case ASCENDING: return this.theK.compareTo(e2.theK); case MAX: case DESCENDING: default: return e2.theK.compareTo(this.theK); } } } /** The default size of the heap. This corresponds to a max depth or 10. */ private static final int CAPACITY = 1032; /** The array that holds the heap. */ private Entry[] backArray; /** The number of items actually in he heap. */ private int size; /** The way in which the heap is ordered */ final private Ordering order; /** * Initialize the priority queue with default values. * Make a min heap with the default size */ public PriorityQHeap() { this(Ordering.MIN, CAPACITY); } /** * Initialize a heap. * @param order the order in which items are retrieved from the heap. * @param capacity the max number of items in the heap. */ public PriorityQHeap(Ordering order, int capacity) { this.order=order; backArray = new Entry[capacity]; } @Override public int size() { return size; } @Override public boolean isEmpty() { return size==0; } @Override public boolean offer(K key, V value) { if (size>=(backArray.length-1)) return false; // put new item in at end data items int loc = size++; backArray[loc] = new Entry(key, value); // up heap int upp = (loc-1)/2; //the location of the parent while (loc!=0) { if (0 > backArray[loc].doCompare(backArray[upp])) { // swap and climb Entry tmp = backArray[upp]; backArray[upp] = backArray[loc]; backArray[loc] = tmp; loc = upp; upp = (loc-1)/2; } else { break; } } return true; } /** * Remove the first item in the heap. \ * That is, the item at the 0 position in the underlying array. */ private void removeTop() { size--; // move the last element to the first backArray[0] = backArray[size]; // set the last item to null so the garbage collector can work. backArray[size]=null; // move the top element down as needed to restore heap ordering property int upp=0; // the location of the item to consider moving down. while (true) { int dwn; // the location of the item to move down to (if appropriate) int dwn1 = upp*2+1; // the left child if (dwn1>=size) break; int dwn2 = upp*2+2; // the right chold if (dwn2>=size) { dwn=dwn1; } else { // determine which is to be preferred, the left or righ child int cmp = backArray[dwn1].doCompare(backArray[dwn2]); if (cmp<=0) dwn=dwn1; else dwn=dwn2; } // determine if parent and child should swap positions. if (0 > backArray[dwn].doCompare(backArray[upp])) { Entry tmp = backArray[dwn]; backArray[dwn] = backArray[upp]; backArray[upp] = tmp; upp=dwn; } else { // if the should not swap, then complete. break; } } } @Override public V poll() { if (isEmpty()) return null; Entry tmp = backArray[0]; removeTop(); return tmp.theV; } @Override public V peek() { if (isEmpty()) return null; return backArray[0].theV; } public static void main(String[] args) { PriorityQHeap pq = new PriorityQHeap<>(Ordering.MIN, CAPACITY); pq.offer(1,"Jane"); pq.offer(10,"WET"); pq.offer(5, "WAS"); System.out.println(pq.poll()); System.out.println(pq.poll()); System.out.println(pq.poll()); System.out.println(); pq = new PriorityQHeap<>(Ordering.MAX, CAPACITY); pq.offer(1,"Jane"); pq.offer(10,"WET"); pq.offer(5, "WAS"); System.out.println(pq.poll()); System.out.println(pq.poll()); System.out.println(pq.poll()); } }