package com.cn.test.tree;
import java.util.Arrays;
public class HeapSortSelf {
public static void heapSort(int[] data){
//1、构建大顶堆
//第一个非叶子节点的坐标 int a = data.length/2 -1
for(int i = data.length/2-1;i>=0;i--){
buildHeap(data,i,data.length);
}
System.out.println("构建完大顶堆后的数据:"+Arrays.toString(data));
//2、把最大值,放在数组的后面,然后再调整堆为大顶堆
for (int i = data.length-1; i>0; i--){
//把最大数据放在数组末尾
int temp = data[0];
data[0] = data[i];
data[i] = temp;
//再调整大顶堆
buildHeap(data,0,i-1);
}
}
/**
* 调整完之后,要再调整子树
* 1、i*2+1是左子节点
* 2、i*2+2是右子节点
* 3、
* @param data
* @param index
* @param length
*/
public static void buildHeap(int[] data,int index,int length){
//记录左右结点中较大的下标
int adjustIndex = 0;
for(int i = index;i*2+1<length;){
/**
* 找出左右节点中较大的下标,存储到adjustIndex里
*/
if( i*2+2<length && data[i*2+1] < data[i*2+2]){
adjustIndex = i*2+2;
}else {
adjustIndex = i*2+1;
}
/**
* 父节点与最大的子节点的数据对比,如果父节点大,就对比结束
* 如果父节点小,则让父节点与子节点交换数据,然后再调整子节点为大顶堆
*/
if(data[i]<data[adjustIndex]){
int temp = data[i];
data[i] = data[adjustIndex];
data[adjustIndex] = temp;
i = adjustIndex;
}else {
/**
* 在这里只所有能退出,是因为data在调用这个方法时,已经实现了大顶堆,只需要调整节点变动的子树就可以,
* 如果节点没有变动,则不用再调整了
*/
break;
}
}
}
public static void main(String[] args) {
int[] data = {4,10,1,6,9,5,20,15,30,100,-1,90,90,9};
heapSort(data);
System.out.println("排序之后的数组:"+Arrays.toString(data));
}
}
打印的结果是:
构建完大顶堆后的数据:[100, 30, 90, 15, 10, 90, 20, 4, 6, 9, -1, 5, 1, 9]
排序之后的数组:[-1, 1, 4, 5, 6, 9, 9, 10, 15, 20, 30, 90, 90, 100]