一.概念
二叉堆在逻辑上可以看成一个完全二叉树,其物理结构是一个数组,映射关系如下
· 树上的每个节点对应数组上的一个元素
· Parent(i) return array[i/2] ; Left[i] return array[2*i]; Right(i) return array[2*i+1];(注意对应的物理数组下标从1开始)
二. 主要算法
· maxHeapity(维护最大堆) 时间复杂度 O(nlgn).
` buildMaxHeap(创建最大堆) O(n)
` insert, extractMax, increaseKey, O(lgn)
三. 算法的实现
import java.util.ArrayList;
/**
* 自己实现一个堆类
* 对于其逻辑结构,类似于一颗排序树,对于其物理结构,用一个数组来维护(可以采用ArrayList)。
* 映射关系满足如下
* PARENT(i) return i/2;
* LEFT(i) return 2*i;
* RIGHT(i) return 2*i+1;
* @author Neuclil
*
*/
public class Heap {
private int[] array;
private int length;
public Heap(int[] array){
buildMaxHeap(array);
}
public int getSize(){
return length;
}
public int parentIndex(int i){
return i/2;
}
public int leftChiledIndex(int i){
return 2*i;
}
public int rightChildIndex(int i){
return 2*i+1;
}
//调整最大堆
private void maxHeapify(int[] array, int i){
int largest = i;
int l = leftChiledIndex(i);
int r = rightChildIndex(i);
if(l <= getSize()){
if(array[i] < array[l])
largest = l;
else
largest = i;
}else
largest = i;
if(r <= getSize())
if(array[largest] < array[r])
largest = r;
if(largest != i){
int temp = array[i];
array[i] = array[largest];
array[largest] = temp;
maxHeapify(array, largest);
}
}
//构建最大堆
private void buildMaxHeap(int[] array){
this.array = array;
this.length = array.length-1;//length = 10;
for(int i =length/2; i>=1; i--){
maxHeapify(array, i);
}
}
public int get(int i){
return array[i];
}
//对其排序
public void sort(){
int oldLength = length;
for(int i = length; i>=2; i--){
int temp = array[1];
array[1] = array[i];
array[i] = temp;
length--;
maxHeapify(array, 1);
}
length = oldLength;
}
//抽取出最大堆的最大值
public int extractMax(){
if(getSize()<1){
System.out.println("heap underflow");
return -Integer.MAX_VALUE;
}
int max = array[1];
array[1] = array[length];
length--;
maxHeapify(array, 1);
return max;
}
//改变某个i下标变量的值
public void increaseKey(int i, int key){
if(key < array[i])
return ;
array[i] = key;
while(i>1 && array[parentIndex(i)] < array[i]){
int temp = array[parentIndex(i)];
array[parentIndex(i)] = array[i];
array[i] = temp;
i = parentIndex(i);
}
}
//插入元素
public void insert(int key){
int[] newArray = new int[length+2];
System.arraycopy(array, 0, newArray, 0, length+1);
array = newArray;
length++;
array[length] = Integer.MIN_VALUE;
increaseKey(length, key);
}
}
四.应用
操作系统中作业的调度所涉及的优先队列。
基于事件驱动的模拟器。