// // ******************PUBLIC OPERATIONS********************* // void insert( x ) --> Insert x // Comparable deleteMin( )--> Return and remove smallest item // Comparable findMin( ) --> Return smallest item // boolean isEmpty( ) --> Return true if empty; else false // ******************ERRORS******************************** // Throws RuntimeException for findMin and deleteMin when empty package org.insa.algo.utils; import java.util.ArrayList; /** * Implements a binary heap. Note that all "matching" is based on the compareTo * method. * * @author Mark Allen Weiss * @author DLB */ public class BinaryHeap> { // Number of elements in heap. private int currentSize; // The heap array. Java genericity does not work with arrays so we have to use // an ArrayList. private ArrayList array; /** * Construct a new empty binary heap. */ public BinaryHeap() { this.currentSize = 0; this.array = new ArrayList(); } /** * Construct a copy of the given heap. * * @param heap Binary heap to copy. */ public BinaryHeap(BinaryHeap heap) { this.currentSize = heap.currentSize; this.array = new ArrayList(heap.array); } /** * Set an element at the given index. * * @param index Index at which the element should be set. * @param value Element to set. */ private void arraySet(int index, E value) { if (index == this.array.size()) { this.array.add(value); } else { this.array.set(index, value); } } /** * @return Index of the parent of the given index. */ private int index_parent(int index) { return (index - 1) / 2; } /** * @return Index of the left child of the given index. */ private int index_left(int index) { return index * 2 + 1; } /** * Internal method to percolate up in the heap. * * @param index Index at which the percolate begins. */ private void percolateUp(int index) { E x = this.array.get(index); for (; index > 0 && x.compareTo(this.array.get(index_parent(index))) < 0; index = index_parent( index)) { E moving_val = this.array.get(index_parent(index)); this.arraySet(index, moving_val); } this.arraySet(index, x); } /** * Internal method to percolate down in the heap. * * @param index Index at which the percolate begins. */ private void percolateDown(int index) { int ileft = index_left(index); int iright = ileft + 1; if (ileft < this.currentSize) { E current = this.array.get(index); E left = this.array.get(ileft); boolean hasRight = iright < this.currentSize; E right = (hasRight) ? this.array.get(iright) : null; if (!hasRight || left.compareTo(right) < 0) { // Left is smaller if (left.compareTo(current) < 0) { this.arraySet(index, left); this.arraySet(ileft, current); this.percolateDown(ileft); } } else { // Right is smaller if (right.compareTo(current) < 0) { this.arraySet(index, right); this.arraySet(iright, current); this.percolateDown(iright); } } } } /** * @return true if the heap is empty, false otherwise. */ public boolean isEmpty() { return this.currentSize == 0; } /** * @return Current size (number of elements) of this heap. */ public int size() { return this.currentSize; } /** * Insert the given element into the heap. * * @param x Item to insert. */ public void add(E x) { int index = this.currentSize++; this.arraySet(index, x); this.percolateUp(index); } /** * Tell the binary heap that the given element has been modified and should be * re-positioned inside the heap. * * @param x Item to update. */ public void update(E x) { // TODO: } /** * Find the smallest item in the heap. * * @return The smallest item in the heap. * * @throws RuntimeException if this heap is empty. */ public E findMin() throws RuntimeException { if (isEmpty()) throw new RuntimeException("Empty binary heap."); return this.array.get(0); } /** * Remove the smallest item from the heap. * * @return The smallest item in the heap. * * @throws RuntimeException if this heap is empty. */ public E deleteMin() throws RuntimeException { E minItem = findMin(); E lastItem = this.array.get(--this.currentSize); this.arraySet(0, lastItem); this.percolateDown(0); return minItem; } /** * Prints the heap */ public void print() { System.out.println(); System.out.println("======== HEAP (size = " + this.currentSize + ") ========"); System.out.println(); for (int i = 0; i < this.currentSize; i++) { System.out.println(this.array.get(i).toString()); } System.out.println(); System.out.println("-------- End of heap --------"); System.out.println(); } /** * Prints the elements of the heap according to their respective order. */ public void printSorted() { BinaryHeap copy = new BinaryHeap(this); System.out.println(); System.out.println("======== Sorted HEAP (size = " + this.currentSize + ") ========"); System.out.println(); while (!copy.isEmpty()) { System.out.println(copy.deleteMin()); } System.out.println(); System.out.println("-------- End of heap --------"); System.out.println(); } }