Java实现堆排序

public class HeapSort implements SortAlgorithm {

    @Override
    public void sort(int[] nums) {
        if (nums == null || nums.length == 0) return;
        // 构建最大堆
        buildMaxHeap(nums);
        int heapSize = nums.length;
        while (heapSize > 1) {
            // 交换堆顶和堆尾的两个元素
            swap(nums, h2a(1), h2a(heapSize));
            // 堆的大小-1
            --heapSize;
            // 调整堆顶元素
            heapify(nums, heapSize, 1);
        }
        System.out.println("heap sort:" + Arrays.toString(nums));
    }

    // 构建最大堆
    private void buildMaxHeap(int[] nums) {
        for (int i = nums.length / 2; i >= 1; --i) {
            heapify(nums, nums.length, i);
        }
        System.out.println("max heap: " + Arrays.toString(nums));
    }

    // 对元素i进行调整,以维护最大堆的性质
    // 原数组元素下标从0开始,需要从1开始
    private void heapify(int[] nums, int heapSize, int heapIndex) {
        // 如果是叶子节点,则不需要调整
        if (heapIndex > heapSize / 2) return;
        // 如果有孩子节点
        int leftChildIndex = 2 * heapIndex;
        int rightChildIndex = leftChildIndex + 1;
        // 找出父节点以及左右孩子节点中的最大者
        int largestIndex = nums[h2a(heapIndex)] >= nums[h2a(leftChildIndex)] ? heapIndex : leftChildIndex;
        if (rightChildIndex <= heapSize && nums[h2a(rightChildIndex)] > nums[h2a(largestIndex)]) {
            largestIndex = rightChildIndex;
        }
        // 如果父节点的值不是最大
        if (heapIndex != largestIndex) {
            // 交换两个元素
            swap(nums, h2a(heapIndex), h2a(largestIndex));
            // 递归调整
            heapify(nums, heapSize, largestIndex);
        }
    }

    // 交换数组中两个元素
    private void swap(int[] nums, int i, int j) {
        int t = nums[i];
        nums[i] = nums[j];
        nums[j] = t;
    }

    // 将堆的编号转化为数组下标
    private int h2a(int heapIndex) {
        return heapIndex - 1;
    }

    public static void main(String[] args) {
        int[] nums = new int[]{7, 5, 6, 9, 11, 2, 7};
        new HeapSort().sort(nums);
    }
}
posted @ 2020-05-20 11:26  SanjiApollo  阅读(230)  评论(0编辑  收藏  举报