堆(优先队列)
二叉堆
二叉堆常常用于优先队列的实现。
堆是一个被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左到右填入。
因为二叉堆是完全二叉树,所以可以使用数组表示,而不需要使用链表。(使用链表似乎代码实现方便点)
堆序性质
任意节点的值都小于它所有字节点的值
代码实现
/**
* 二叉堆
* 将堆数据存放在数组内,对自上而下,自左而右的数据依次放到数组中,数组索引从1开始,即array[0]不存放数据
*/
public class BinaryHeap {
public BinaryHeap(){}
public BinaryHeap(int x){
currentSize++;
array[currentSize]=x;
}
public BinaryHeap(int[] items){
currentSize=items.length;
array = new int[(currentSize+2)*11/10];
int i=1;
for(int item:items){
array[i++]=item;
}
buildHeap();
}
public void insert(int x){
if(currentSize==array.length-1) enlargeHeap(array.length*2+1);
//hole代表空穴的位置
int hole = ++currentSize;
//空穴的位置上浮
for(;hole>1 && x<(array[hole/2]);hole/=2){
array[hole]=array[hole/2];
}
//最后空穴的位置为hole
//将x放入空穴
array[hole]=x;
}
public int findMin() throws Exception{
if(isEmpty()) throw new Exception("堆为空");
return array[1];
}
public int deleteMin()throws Exception{
if(isEmpty()) throw new Exception("无法对空堆作删除操作");
int min = findMin();
//把最后一个元素放在首位,并减小堆大小currentSize
array[1]=array[currentSize--];
//然后调整堆第一个元素的位置
percolateDown(1);
return min;
}
public boolean isEmpty(){
return currentSize==0;
}
public void makeEmpty(){
currentSize=0;
}
private static final int DEFAULT_CAPCITY=10;
private int currentSize=0;
private int[] array;
//对hole位置的元素做下沉操作
private void percolateDown(int hole){
int child=0;
int tmp = array[hole];
for(;hole*2<=currentSize;hole=child){
child=hole*2;
if(child!=currentSize && array[child+1]<array[child]) child++;
if(array[child]<tmp) array[hole]=array[child];
else break;
}
array[hole]=tmp;
}
private void buildHeap(){
for (int i=currentSize/2;i>0;i--){
percolateDown(i);
}
}
private void enlargeHeap(int newSize){
if(newSize<=array.length) return;
int[] tmp = new int[newSize];
for(int i=1;i<=currentSize;i++){
tmp[i]=array[i];
}
array=tmp;
}
}
联系方式:wuchaodzxx@126.com

浙公网安备 33010602011771号