排序算法(三):堆排序

1.Heap.class

package cn.sort.heap;


/**
 * 堆排序实现:升序排序
 * @author LY
 *
 */
public class Heap {
    /**
     * 打印数组
     * @param arr
     * @param size
     */
    public static void printArr(Integer[] arr, int size) {
        System.out.println("打印结果为:");
        for(int i = 0; i < size; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    /**
     * 向下调整:先拿左右子树进行比较,看谁比较大,
     * 然后再拿大的与父结点进行比较,若孩子结点比较大,则大孩子与父结点交换,继续调整
     * @param arr
     * @param size
     * @param index
     */
    private static void AdjustDown(Integer[] arr, int size, int index) {
        int parent = index;
        int child = 2 * parent + 1; // 左子树

        while(child < size) {
            // 先拿左右子树进行比较,看谁比较大,
            if(child + 1 < size && arr[child + 1] > arr[child]) {
                // 右子树比左子树大,就让child 指向右子树
                child = child + 1;
            }

            // 然后再拿大的与父结点进行比较,若孩子结点比较大,则大孩子与父结点交换
            if(arr[child] > arr[parent]) {
                int tmp = arr[child];
                arr[child] = arr[parent];
                arr[parent] = tmp;  
            }
            else {
                // 此时调整就已经调整完了
                break;
            }

            // 交换后破坏堆结构,继续调整,直到满足堆
            parent = child;
            child = 2 * parent + 1;
        }
        return;
    }

    /**
     * 建大堆 :
     * 下沉式调整,需要从后往前遍历从最后一个非叶子结点开始遍历 (size - 1 - 1) / 2 
     * size - 1 表示最后一个元素的下标 
     * 拿着这个下标-1 / 2 就得到当前元素的父节点
     * @param arr 数组
     * @param size 数组大小
     */
    private static void CreateHeap(Integer[] arr, int size) {
        if(size <= 1) {
            return;
        }
        // 下沉式调整,需要从后往前遍历
        // 从最后一个非叶子结点开始遍历 (size - 1 - 1)/ 2
        // size - 1 表示最后一个元素的下标
        // 拿着这个下标-1 / 2 就得到当前元素的父节点
        int parent = (size - 1 - 1) / 2;
        for(int i = parent; i >= 0; i--) {
            AdjustDown(arr, size, i);
        }
    }

    /**
     * 堆删:将堆顶元素与最后一个元素交换,然后对堆顶(从0下标)进行向下调整
     * @param arr 数组
     * @param size 数组大小
     */
    private static void heapPop(Integer[] arr, int size) {
        if(size <= 1) {
            return;
        }

        // 交换堆顶元素与最后一个元素
        int tmp = arr[0];
        arr[0] = arr[size - 1];
        arr[size - 1] = tmp;    

        // 关键在于 size - 1,相当于删除了一个元素,对交换后的最后元素不处理
        AdjustDown(arr, size - 1, 0); 
    }

    /**
     * 堆排序:升序
     * @param arr 数组
     */
    public static void heapSort(Integer[] arr) {
        if(arr == null) {
            return;
        }
        int size = arr.length;

        // 1. 建大堆
        CreateHeap(arr, size);

        // 2. 循环删除堆顶元素,最大元素依次到了队尾
        for(int i = 0; i < size; i++) {
            heapPop(arr, size - i);
        }
    }

}

2.Test.class

package cn.sort.heap;

public class Test {
    public static void main(String[] args) {
        Integer[] arr = {9, 5, 2, 7};
        int size = arr.length;

        Heap.heapSort(arr);
        Heap.printArr(arr, size);
    }

}

3.截图
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39026129/article/details/81389632