1.排升序,建大堆
        public static void heapSort(int[] array) {
                //将数组建成大堆
                heapify(array);
                for(int i = 0; i < array.length - 1; i++) {
                        //交换前
                        //无序区间[0, array.length - i);
                        //有序区间[array.length - i, array.length);
                        swap(array, 0, array.length - 1 - i);
                        //交换后
                        //无序区间[0, array.length - i - 1)
                        //有序区间[array.length - i - 1, array.length)
                        //无序区间的长度 array.length - i - 1
                        siftDown(array, array.length - i - 1, 0);
                }
        }
        private static void swap(int[] array, int i, int j) {
                int tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
        }
        private static void heapify(int[] array) {
                //array.length - 1 是堆的最后一个结点的下标,
                //则最后一个非叶子结点的下标就是 (array.length - 1 - 1) >>> 1
                for(int i = (array.length - 1 - 1) >>> 1; i >= 0; i--) {
                        siftDown(array, array.length, i);
                }
        }
        private static void siftDown(int[] array, int length, int index) {
                int left = (index << 1) + 1;
                while(left < length) {
                        int right = (index << 1) + 2;
                        int max = left;
                        //右结点存在且值比左节点的值大时,值最大的结点才是右结点
                        if(right < length && array[right] > array[max]) {
                                max = right;
                        }
                        //如果需要调整的结点的值比子结点中值最大的结点的值都大时,向下调整结束
                        if(array[index] >= array[max]) {
                                break;
                        }
                        swap(array, index, max);
                        index = max;
                        left = (index << 1) + 1;
                }
        }
2.排降序,建小堆
        public static void heapSort(int[] array) {
                //将数组建成小堆
                heapify(array);
                for(int i = 0; i < array.length - 1; i++) {
                        //交换前
                        //无序区间[0, array.length - i);
                        //有序区间[array.length - i, array.length);
                        swap(array, 0, array.length - 1 - i);
                        //交换后
                        //无序区间[0, array.length - i - 1)
                        //有序区间[array.length - i - 1, array.length)
                        //无序区间的长度 array.length - i - 1
                        siftDown(array, array.length - i - 1, 0);
                }
        }
        private static void swap(int[] array, int i, int j) {
                int tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
        }
        private static void heapify(int[] array) {
                //array.length - 1 是堆的最后一个结点的下标,
                //则最后一个非叶子结点的下标就是 (array.length - 1 - 1) >>> 1
                for(int i = (array.length - 1 - 1) >>> 1; i >= 0; i--) {
                        siftDown(array, array.length, i);
                }
        }
        private static void siftDown(int[] array, int length, int index) {
                int left = (index << 1) + 1;
                while(left < length) {
                        int right = (index << 1) + 2;
                        int min = left;
                        if(right < length && array[right] < array[min]) {
                                min = right;
                        }
                        if(array[index] <= array[min]) {
                                break;
                        }
                        swap(array, index, min);
                        index = min;
                        left = (index << 1) + 1;
                }
        }
原文:https://blog.51cto.com/14233687/2472009