堆排序

前言

算法就是枯燥无味的,需要自己耐心去学习。

堆排序是什么?

一个不断调整堆的排序算法。

堆排序的应用场景

1、使用于数据量很大的情况。比如找出1000w数据中最小的前100个数字。建立一百个节点的大顶堆,首先将前一百个数放入堆中,之后每放入一个数就删除一个堆顶元素,最后剩下的就是最小的100个数。

与其他排序算法相比

1、数据量比较小的时候,选择排序是最快的。
2、当不仅仅需要排序,而是要取一个数据比较多的数组中的前n个数,可以考虑使用堆排序。

堆排序流程图

1、将无序数组构建成一个堆,根据升序需求选择大顶堆;
2、将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
3、重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

源码

public class Solution {
    public static void main(String[] args) {
        int[] arr = {2, 1, 5, 4, 6, 3, 7};
        sortHeap(arr);
        showArr(arr);
    }

    /**
     * 建立大顶堆。从倒数第二层最右边的父节点开始调整堆。
     * len并不总是数组的真实长度,而是你想调整的数组的长度。
     */
    public static void buildMaxHeap(int[] arr, int len) { 
        int last = len - 1;
        int parent = (last - 1) / 2;
        for (int i = parent; i >= 0; i--) {
            heapify(arr, len, i);
        }
    }

    /**
     * 调整为二叉堆
     *
     * len并不总是数组的真实长度,而是你想调整的数组的长度。
     *
     * 易错点:两个if语句,必须写max而不是写parent。因为要确认左右子树与根的关系
     *
     */
    public static void heapify(int[] arr, int len, int parent) {
        int left = parent * 2 + 1;
        int right = parent * 2 + 2;
        int max = parent;

        if (left < len && arr[left] > arr[max]) {
            max = left;
        }

        if (right < len && arr[right] > arr[max]) {
            max = right;
        }

        if (max != parent) {
            swap(arr, max, parent);
            heapify(arr, len, max); //堆调整之后,子节点可能也需要调整。
        }
    }

    /**
     * 对堆进行排序。首先将第一个顶点输出,将第一个节点与最后一个节点交换,然后调整堆
     */
    public static void sortHeap(int[] arr){
        buildMaxHeap(arr,arr.length);
        for (int i = arr.length-1; i >=0; i--) {
            swap(arr,0,i);
            //建立堆:数组以及数组需要调整的长度。因为放在后面的最大元素我是不想再动的
            buildMaxHeap(arr,i);
        }
    }

    
    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }


    public static void showArr(int[] arr) {
        for (int value : arr) {
            System.out.print(value + " ");
        }
        System.out.println();
    }
 }
posted @ 2021-02-25 23:01  羽绒333  阅读(146)  评论(0编辑  收藏  举报