版权声明:欢迎转载并请注明出处,谢谢~~ https://blog.csdn.net/chimomo/article/details/85253138
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
*/