• 堆排序


    前言

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

    堆排序是什么?

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

    堆排序的应用场景

    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();
        }
     }
    
  • 相关阅读:
    SharePoint 2010 Crawl Component Stuck in “Recovering” status
    什么是Named Pipes
    请不要修改FIM的配置, 否则SharePoint的User Profile无法获得微软支持
    经典的SharePoint 2010升级中的多核CPU冲突问题
    怎样才能比较方便地查看PowerShell里返回回来的对象的每个成员及它们的值呢?
    如何打开证书控制台
    浏览器: F5 和 Ctrl+F5的区别
    关于用户角色权限管理的探讨
    支付宝接口源代码
    海量数据处理
  • 原文地址:https://www.cnblogs.com/YuRong3333/p/14449906.html
Copyright © 2020-2023  润新知