堆就是满足一定条件的完全二叉树,大根堆的这个条件就是父节点的值不小于左右子节点的值。它的值是按从上往下,从左往右的顺序(从1开始)。左子节点的值=父节点值* 2,而右节点值= 父节点值*2+1。
堆排序的算法过程是按照序列顺序生成一个堆,随后从根节点从上至向从左至开始不断的调整堆使其形成一个最大堆,然后取出根节点就是该序列的最大值,对剩下来的子序列进行调整,又形成最大堆。重复上面的步骤,直到堆中元素只有一个。整体来说堆排序包括调整堆,形成最大堆。
public class HeapSort {
public static void heapSort(int[] data){
buildMaxHeap(data);
for (int i = data.length; i > 1; i--) {
int tmp = data[0];
data[0] = data[i - 1];
data[i - 1] = tmp;
adjustHeapify(data, 1, i - 1);
}
}
/*
* 形成最大堆
*/
private static void buildMaxHeap(int[] data){
for(int i=data.length/2;i>0;i--){
adjustHeapify(data,i,data.length);
}
}
/*
* 调整堆
* @Parameter 序列data,父节点序号i,堆大小heapSize
*/
private static void adjustHeapify(int[] data,int i,int heapSize){
int l=i*2;
int r=i*2+1;
int largest=i;
// 如果左子节点大于父节点,则将左子节点作为最大节点
if (l <= heapSize && data[l-1]>data[i-1]) {
largest = l;
}
// 如果右子节点比最大节点还大,那么最大节点应该是右子节点
if (r <= heapSize && data[r-1]>data[largest-1]) {
largest = r;
}
if(largest!=i){
int temp=data[largest-1];
data[largest-1]=data[i-1];
data[i-1]=temp;
adjustHeapify(data,largest,heapSize);//重复比较
}
}
public static void main(String[] args){
int [] data={4,1,3,2,16,9,10,14,8,7};
heapSort(data);
for(int i=0;i<data.length;i++){
System.out.print(data[i]+",");
}
}
}
对上述代码执行后的结果如下