原理可以看这里:https://www.jianshu.com/p/0d383d294a80
这位朋友讲的相当透彻
下面是我的实现,可以参考
public class HeapSort {
/**
* 交换值
* @param arr
* @param a(第一个数在数组中位置)
* @param b(第二个数在数组中位置)
* @return
*/
public static int[] changeValue(int[] arr, int a,int b){
if (a!=b) {
int k = arr[a];
arr[a] = arr[b];
arr[b] = k;
}
return arr;
}
/**
* 排序
* @param arr
* @return
*/
public static int[] sort(int[] arr){
//数组长度小于等于一则不用排序直接返回
if (arr.length<=1){
return arr;
}
int[] resault = arr;
//找到最后一个非叶子节点,依次往前遍历所有非叶子节点
for (int i=arr.length/2-1;i>=0;i--){
//判断是否存在右孩子
if (arr.length>2*i+2){
//判断左右孩子谁更大
if (resault[2*i+1]>=resault[2*i+2]){
//用较大的那个和当前节点比较,若比当前节点大,则交换值
if (resault[i]<resault[2*i+1]){
changeValue(resault,i,2*i+1);
}
}else{
//用较大的那个和当前节点比较,若比当前节点大,则交换值
if (resault[i]<resault[2*i+2]){
changeValue(resault,i,2*i+2);
}
}
}else {
//只有左孩子判断左孩子和当前节点谁的值更大
if (resault[i]<resault[2*i+1]){
changeValue(resault,i,2*i+1);
}
}
}
if (resault.length-1>0){
//大根堆构建完成,把根和最后一个叶子节点交换,即把最大值放置数组尾
changeValue(resault,0,resault.length-1);
//去掉最后一个节点,再进行排序
int[] arr2 = new int[resault.length-1];
for (int k=0;k<resault.length-1;k++){
arr2[k] = resault[k];
}
arr2 = sort(arr2);
for (int k=0;k<arr2.length;k++){
resault[k] = arr2[k];
}
}
return resault;
}
}