排序算法-堆排序

思路:

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);
    }
}

 

posted @ 2021-05-05 13:30  wsZzz1997  阅读(54)  评论(0编辑  收藏  举报