优先队列、堆、二叉堆在本文都指的是二叉堆
class BinaryHeap<AnyType extends Comparable<? super AnyType>>
{
//定义默认容量、数组大小、数组
private static final int DEFAULT_CAPACITY = 10;
private int currentSize = 0;
private AnyType[] array;
//构造二叉堆
//默认构造
public BinaryHeap()
{
this(DEFAULT_CAPACITY);
}
//带容量的构造
@SuppressWarnings("unchecked")
public BinaryHeap(int capacity)
{
currentSize = 0;
//无法直接创建泛型数组,需要创建其非泛型的父类并强制类型转换
//capacity + 1 :数组零角标不存放元素
array = (AnyType[])new Comparable[capacity + 1];
}
//带数组的构造
@SuppressWarnings("unchecked")
public BinaryHeap(AnyType[] items)
{
currentSize = items.length;
array = (AnyType[])new Comparable[(currentSize + 2) * 11 / 10];//?????
int i = 1;
for(AnyType item : items)
array[i++] = item;
buildHeap();
}
//makeEmpty方法
public void makeEmpty()
{
currentSize = 0;
}
//isEmpty方法
public boolean isEmpty()
{
return currentSize == 0;
}
//insert方法
public void insert(AnyType x)
{
//判断是否需要扩容
if(currentSize == array.length - 1)
enlargeArray(array.length * 2 + 1);
//上升
int hole = ++currentSize;//空洞在末端,数组长度加一
//确定空洞位置,不断与其父亲比较
for(array[0] = x; x.compareTo(array[hole / 2]) < 0 ; hole /=2 )
array[hole] = array[hole / 2];
array[hole] = x;
}
//enlargeArray方法
private void enlargeArray(int newSize)
{
AnyType [] old = array;
array = (AnyType[])new Comparable[newSize];
for(int i = 0; i < old.length; i++)
array[i] = old[i];
}
//findMin方法
public AnyType findMin()
{
if(isEmpty())
throw new RuntimeException();
return array[1];
}
//deleteMin方法
public AnyType deleteMin()
{
if(isEmpty())
throw new RuntimeException();
AnyType minItem = findMin();
array[1] = array[currentSize--];
percolateDown(1);
return minItem;
}
//bulidHeap方法:将该数组变为二叉堆,将除树叶之外的都进行一次下沉
private void buildHeap()
{
for( int i = currentSize/2; i > 0 ; i--)
percolateDown(i);
}
//percolateDown下沉方法
private void percolateDown(int hole)
{
int child;
AnyType tmp = array[hole];
//寻找两个子树中最小的子树,并与其比较大小,若小于子树,则与子树交换元素,即下沉一次
for(;hole * 2 <= currentSize; hole = child)
{
child = hole * 2 ;
if(child != currentSize && array[child + 1].compareTo(array[child]) < 0)
child++;
if(array[child].compareTo(tmp) < 0)
array[hole] = array [child];
else
break;
}
array[hole] = tmp;
}
}