堆的相关性质:1.堆的类型:以数组实现的完全二叉树
2.特点:每个节点的元素值不小于其子节点的元素值,所以删除最大值只需要删除根节点。
可以用数组实现堆的精髓点在于:每个子节点的下标 i 除 2 得到父节点的下标(这是完全二叉树所具备的)
int i = ++H.size; //i指向插入元素后堆中最后一个元素的位置
//为向下过滤节点,只要插入的数据小于父节点,便把它到根结点的所有节点后移
for( ; H.data[i/2]<item; i/=2) {
H.data[i] = H.data[i/2];
}
H.data[i] = item;
上代码:
public class MaxHeap {
public static final int MaxData = 99999; //定义哨兵的值
int[] data; //储存堆元素的数组
int size; //堆的当前元素的个数
int capacity; //堆的最大容量
public MaxHeap create(int MaxSize) {
MaxHeap maxHeap = new MaxHeap();
maxHeap.data = new int[MaxSize*MaxSize];
maxHeap.size = 0;
maxHeap.capacity = MaxSize;
maxHeap.data[0] = MaxData; //建立哨兵,方便操作
return maxHeap;
}
public boolean IsFull(MaxHeap H) {
if(H.size == H.capacity) {
return true;
}
return false;
}
public boolean IsEmpty(MaxHeap H) {
if(H.size == 0) {
return true;
}
return false;
}
public void insert(MaxHeap H, int item) {
if(IsFull(H)) {
System.out.println("最大堆已满");
return;
}
int i = ++H.size; //i指向插入元素后堆中最后一个元素的位置
//这里利用堆(完全二叉树)的性质,每个子节点i/2必定得到父节点。称为向下过滤节点
for( ; H.data[i/2]<item; i/=2) {
H.data[i] = H.data[i/2];
}
H.data[i] = item;
}
public int deleteMax(MaxHeap H) {
int parent,child;
int MaxItem,temp;
if(IsEmpty(H)) {
System.out.println("最大堆已空");
return 0;
}
MaxItem = H.data[1];
temp = H.data[H.size--];
//parent*2<H.size说明有儿子(左右至少一个)
for(parent = 1; parent*2<H.size; parent = child) {
child = parent*2; //假设左儿子为最大值
//child != H.size说明有右儿子,H.data[child]<H.data[child+1]右儿子更大
if((child != H.size)&&(H.data[child]<H.data[child+1])) {
child++;
}
if(temp>=H.data[child]) {
break;
}
else {
H.data[parent] = H.data[child];
}
}
H.data[parent] = temp;
return MaxItem;
}
}
简单写个测试类:
package maxHeap;
public class Test {
public static void main(String[] args) {
MaxHeap maxHeap = new MaxHeap();
MaxHeap heap = maxHeap.create(10);
maxHeap.insert(heap, 8);
maxHeap.insert(heap, 15);
maxHeap.insert(heap, 55);
maxHeap.insert(heap, 31);
maxHeap.insert(heap, 2);
maxHeap.insert(heap, 9);
maxHeap.insert(heap, 11);
maxHeap.insert(heap, 44);
int size = heap.size;
for(int i=0;i<size;i++) {
int j = maxHeap.deleteMax(heap);
System.out.println(j);
}
}
}
输出结果如下: