堆是一棵具有特殊性质的二叉树,堆的基本性质是堆中所有结点的值必须大于或者等于(或小于等于)其孩子结点的值。这也称为堆的性质。堆可以分为最大堆和最小堆,如果要求结点的值必须大于其孩子结点的值,则称其为最大堆,反之,则称其为最小堆。
堆在形式上表现为一棵完全二叉树。这里,使用数组来建立一个最大堆:假定下标从0开始,所有元素都保存在数组中
public class Heap {
public int[] array;
public int count; //堆中元素的个数
public int capacity; //堆的大小
public int heap_type; //最小堆或最大堆
public Heap(int capacity, int heaptype){
this.capacity = capacity;
this.heap_type = heaptype;
this.count = 0;
this.array = new int[capacity];
}
public int Parent(int i){//通过数组位置的规律得到
if(i<=0 || i>this.count)
return -1;
return (i-1)/2;
}
public void Print(){
for(int i=0;i<this.count;i++)
System.out.print(this.array[i]+" ");
}
//左右孩子
public int LeftChild(int i){
int left = 2*i+1;
if(left>=this.count)
return -1;
else
return left;
}
public int RightChild(int i){
int right = 2*i+2;
if(right>=this.count)
return -1;
return right;
}
public int GetMaximum(){
if(this.count==0)
return -1;
return this.array[0];
}
//堆化当前元素
public void PercolateDown(int i){
int l,r,max,temp;
l = LeftChild(i);
r= RightChild(i);
if (l==-1 && r ==-1)
return;
if(l != -1 && this.array[l]>this.array[i] )
max = l;
else
max = i;
if(r!=-1&&this.array[r]>this.array[max])
max = r;
if(max!=i){
temp = this.array[i];
this.array[i] = this.array[max];
this.array[max] = temp;
PercolateDown(max);
}
}
//删除元素
public int DeleteMax(){
if(this.count==0)
return -1;
int data = this.array[0];
this.array[0] = this.array[this.count-1];
this.count--;
PercolateDown(0);
return data;
}
//插入元素
public int Insert(int data){
int i;
if(this.count == this.capacity)
ResizeHeap();
this.count++;
i = this.count-1;
if(i==0){
this.array[0] = data;
return i;
}
while(i>0 && data> this.array[(i-1)/2]){
this.array[i] = this.array[(i-1)/2];
i=(i-1)/2;
}
this.array[i] = data;
return i;
}
//扩展堆
public void ResizeHeap(){
int[] array_old = new int[this.capacity];
System.arraycopy(this.array, 0, array_old, 0,this.count-1);
this.array = new int[this.capacity*2];
if(this.array==null){
System.out.println("Memory error");
return;
}
for(int i=0;i<this.capacity;i++)
this.array[i] = array_old[i];
this.capacity*=2;
array_old = null;
}
//清空堆
public void DestroyHeap(){
this.count = 0;
this.array = null;
}
//数组建堆,取n个输入元素将它们插入空堆中
public void BuildHeap(Heap h,int[] A,int n){
if(h==null)
return;
while(n > this.capacity)
h.ResizeHeap();
for(int i=0;i<n;i++)
h.array[i] = A[i];
this.count = n;
int max = n-1;
for(int i=(max-1)/2;i>=0;i--)
h.PercolateDown(i);
}
}