本例中实现了最小堆的构造、插入、删除。最小堆表示一个非终端节点均不大于其左右孩子节点。最小堆用完全二叉树表示,但是二叉树存入一维数组中。
将完全二叉树存入数组,有一些性质。先将二叉树从上到下,从左到右给每个节点编号0,1....n。那个一个节点编号i,他的左孩子编号为2*i+1,右孩子编号2*i+2。完全二叉树的最后一个分支节点(非终端节点)为(n-2)/2。
堆的构造:找到最后的分支节点,使用filterDown将它构造成堆。然后在将在该节点前面的子树构造成堆。直到将根节点构造成堆。
....
代码:
public class App
{
public static void main(String[] arg) {
int[] array= {80,57,99,35,23,11,74,29,62,16};
MinHeap minHeap=new MinHeap(array);
System.out.println(Arrays.toString(minHeap.array));
minHeap.insert(14);
System.out.println(Arrays.toString(minHeap.array));
System.out.println(minHeap.deleteTop());
System.out.println(Arrays.toString(minHeap.array));
}
static class MinHeap{
int currentSize;
int [] array;
final static int CAPACITY=30;
MinHeap(int[] array){
this.array=new int[CAPACITY];
for(int i=0;i<array.length;i++) {
this.array[i]=array[i];
}
currentSize=array.length;
int last=(currentSize-2)/2;
while(last>=0) {
filterDown(last);
last--;
}
}
void filterDown(int start) {
int i=start,j=2*i+1;
int temp=array[i];
while(j<currentSize) {
if(j+1<currentSize && array[j]>array[j+1]) {
j++;
}
if(temp>array[j]) {
array[i]=array[j];
i=j;
j=2*i+1;
}else {
break;
}
}
array[i]=temp;
}
void insert(int d) {
if(currentSize==array.length) throw new RuntimeException("head is fulfill");
array[currentSize]=d;
filterUp(currentSize);
currentSize++;
}
void filterUp(int p) {
int j=p,i=(j-1)/2;
int temp=array[j];
while(i>=0) {
if(temp<array[i]) {
array[j]=array[i];
j=i;
i=(j-1)/2;
}else {
break;
}
}
array[j]=temp;
}
int deleteTop() {
int temp=array[0];
array[0]=array[currentSize-1];
currentSize--;
filterDown(0);
return temp;
}
}
}
filterUp的流程图: