Data Structure - Binary Heap (Java)
阿新 • • 發佈:2018-12-29
package chimomo.learning.java.datastructure; /** * Implements a binary heap. * Note that all "matching" is based on the compareTo method. * * @author Created by Chimomo */ public class BinaryHeap<T extends Comparable<? super T>> { private static final int DEFAULT_CAPACITY = 8; // The number of elements in heap. private int size; // The heap array. private T[] array; /** * Construct the binary heap. */ public BinaryHeap() { this(DEFAULT_CAPACITY); } /** * Construct the binary heap. * * @param capacity The capacity of the binary heap. */ public BinaryHeap(int capacity) { size = 0; array = (T[]) new Comparable[capacity + 1]; } /** * Construct the binary heap given an array of items. */ public BinaryHeap(T[] items) { size = items.length; array = (T[]) new Comparable[(size + 2) * 11 / 10]; int i = 1; for (T item : items) { array[i++] = item; } buildHeap(); } // Test program. public static void main(String[] args) throws Exception { int numItems = 10000; // Construct binary heap. BinaryHeap<Integer> binaryHeap = new BinaryHeap<>(); // Insert. for (int i = 37; i != 0; i = (i + 37) % numItems) { binaryHeap.insert(i); } // Find min. System.out.println("Min: " + binaryHeap.findMin()); // Delete min. for (int i = 1; i < numItems; i++) { if (binaryHeap.deleteMin() != i) { System.out.println("Oops! " + i); } } } /** * Insert into the binary heap, maintaining heap order. * Duplicates are allowed. * * @param x The item to insert. */ public void insert(T x) { if (size == array.length - 1) { enlargeArray(array.length * 2 + 1); } // Percolate up. int hole = ++size; for (array[0] = x; x.compareTo(array[hole >> 1]) < 0; hole /= 2) { array[hole] = array[hole >> 1]; } array[hole] = x; } /** * Enlarge array. * * @param newSize The new size of the array. */ private void enlargeArray(int newSize) { T[] old = array; array = (T[]) new Comparable[newSize]; for (int i = 0; i < old.length; i++) { array[i] = old[i]; } } /** * Find the smallest item in the binary heap. * * @return The smallest item, or throw an Exception if empty. */ public T findMin() throws Exception { if (isEmpty()) { throw new Exception("Binary heap is empty!"); } return array[1]; } /** * Remove the smallest item from the binary heap. * * @return The smallest item, or throw an exception if empty. */ public T deleteMin() throws Exception { if (isEmpty()) { throw new Exception("Binary heap is empty!"); } T minItem = findMin(); array[1] = array[size--]; percolateDown(1); return minItem; } /** * Establish heap order property from an arbitrary arrangement of items. * Runs in linear time. */ private void buildHeap() { for (int i = size >> 1; i > 0; i--) percolateDown(i); } /** * Test if the binary heap is logically empty. * * @return True if empty, false otherwise. */ public boolean isEmpty() { return size == 0; } /** * Make the binary heap logically empty. */ public void makeEmpty() { size = 0; } /** * Internal method to percolate down in the heap. * * @param hole The index at which the percolate begins. */ private void percolateDown(int hole) { int child; T tmp = array[hole]; for (; hole << 1 <= size; hole = child) { child = hole << 1; if (child != size && array[child + 1].compareTo(array[child]) < 0) { child++; } if (array[child].compareTo(tmp) < 0) { array[hole] = array[child]; } else { break; } } array[hole] = tmp; } } /* Output: Min: 1 */