import java.util.Random; /** * 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 * Modified: April 13,2020 */ @SuppressWarnings("unchecked") public class PriorityQHeap, V> extends AbstractPriorityQueue { /** 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; /** * 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()); PriorityQHeap pqi = new PriorityQHeap<>(Ordering.MAX, CAPACITY); pqi.poll(); for (int i=0; i<10; i++) pqi.offer(i, i); while (pqi.peek()!=null) System.out.println(pqi.poll()); Random r = new Random(); } }