思路:
1.从最后一个非叶子节点(len/2,len为当前树的长度)开始,将其与左右孩子比较,与较大的孩子交换。到根节点以后,最大(或者最小)的数已经在根了,与最后一个数交换,此时最后一个位置就已经排好了。
2.递归调用,长度-1(最后一个数排好了):sort(a,len-1);
public class HeapSort { // 从最后一个非叶子节点开始,将其与其叶子进行比较,与比它大(或者小)的叶子节点交换 // 一趟过去,最大或者最小的节点放在了堆顶,此时交换堆顶和末尾,然后重复此过程,并缩小排序范围(-1,因为最后的数字已经归位) @Test public void test(){ int [] a = {1,2,5,8,3,4,6,9,7}; sort(a,a.length-1); System.out.println(Arrays.toString(a)); } private void sort(int[] a, int len) { if(len==0){ return; } // 从最后一个非叶子节点开始 for(int i=len/2 ;i>=0 ;i--){ // // 左孩子存在,且大于根 // if(2*i+1 <= len && a[2*i+1]>a[i]){ // a[i] += a[2*i+1]; // a[2*i+1] = a[i] - a[2*i+1]; // a[i] -= a[2*i+1]; // } // // 右孩子存在,且大于根 // if(2*i+2 <= len && a[2*i+2]>a[i]){ // a[i] += a[2*i+2]; // a[2*i+2] = a[i] - a[2*i+2]; // a[i] -= a[2*i+2]; // } if(2*i+2 <= len && 2*i+1 <= len){ if(a[2*i+2] > a[2*i+1] && a[2*i+2] > a[i]){ a[i] += a[2*i+2]; a[2*i+2] = a[i] - a[2*i+2]; a[i] -= a[2*i+2]; }else if(a[2*i+2] <= a[2*i+1] && a[2*i+1] > a[i]){ a[i] += a[2*i+1]; a[2*i+1] = a[i] - a[2*i+1]; a[i] -= a[2*i+1]; } }else if(2*i+1 <= len){ if(a[2*i+1] > a[i]){ a[i] += a[2*i+1]; a[2*i+1] = a[i] - a[2*i+1]; a[i] -= a[2*i+1]; } } } // 将大根(小根)与最后的数交换 a[0] += a[len]; a[len] = a[0] - a[len]; a[0] -= a[len]; // 递归 sort(a,len-1); } }