zoukankan      html  css  js  c++  java
  • 堆排序--leetcode 215

    说明

    本题可以使用quickSelect,PriorityQueue,或者自己构建堆。

    对于要排序的总数是确定的情况下,可以使用quickSelect,对于总数不确定的情况下,可以使用堆排序。

    对于前两种方法本文不说明,本文主要说明堆排序。图片来自于这个up


    堆排序

    堆排序要求整棵树是一个完全二叉树(平衡的),它的数组实现方式对空间利用率很高。

    堆排序的最佳,平均,最坏时间复杂度都是o(nlogn)的,在平均情况下,它比快速排序慢一个常数因子,但是堆排序更适合外部排序,处理那些数据集太大而不适合在内存中排序的情况。

    基于大根堆的排序算法的过程:

    • 建堆
    • 取出堆顶元素(最大值),放到数组的末尾
    • 将堆的最末尾元素放到堆顶,重新构建堆
    • 如此重复,直到堆为空

    建堆

    1. 对于数组中index为i的元素的建堆过程是:先判断2i + 1和2i + 2是否越界,如果不越界,找到这两个index中对应的值最大(最大的值的索引记为max)的和i处的值做交换,同时由于交换了索引对应的值,没法保证索引max的子树还是最大堆,所以要对索引max再次建堆(如果都比i处的值小,就不交换)

    上述过程对应的代码:

    public void heapify(int[] nums, int i, int heapSize){
        int leftChild = 2 * i + 1;
        int rightChild = 2 * i + 2;
        int maxIndex = i;
        if (leftChild < heapSize && nums[leftChild] > nums[maxIndex]){
            maxIndex = leftChild;
        }
        if (rightChild < heapSize && nums[rightChild] > nums[maxIndex]){
            maxIndex = rightChild;
        }
    
        if (maxIndex != i){
            swap(nums, maxIndex, i);
            heapify(nums, maxIndex, heapSize);
        }
    }
    
    public void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }  
    
    1. 最后一个非叶子节点往前倒退,分别对这些节点做heapify,就可以构建出整个堆

    上述过程的代码:

    public void buildMaxHeap(int[] nums, int heapSize){
        for (int i = (heapSize - 1) / 2; i >= 0; i--){
            heapify(nums, i, heapSize);
        }
    }
    

    取出堆顶元素,放到数组末尾。并将堆末尾元素放到堆顶,重新建堆

    执行过程是:交换数组中第一个元素(最大值)和最后一个元素,堆长度-1,对剩下元素重新调整堆。

    代码如下:

    public int findKthLargest(int[] nums, int k) {
        int heapSize = nums.length;
        buildMaxHeap(nums, heapSize);
        for (int i = nums.length - 1; i >= nums.length - k + 1; i--){
            swap(nums, 0, i);
            heapSize--;
            heapify(nums, 0, heapSize);
        }
        return nums[0];
    }
    

    总结

    本题完整代码如下:

    public int findKthLargest(int[] nums, int k) {
        int heapSize = nums.length;
        buildMaxHeap(nums, heapSize);
        for (int i = nums.length - 1; i >= nums.length - k + 1; i--){
            swap(nums, 0, i);
            heapSize--;
            heapify(nums, 0, heapSize);
        }
        return nums[0];
    }
    
    public void buildMaxHeap(int[] nums, int heapSize){
        for (int i = (heapSize - 1) / 2; i >= 0; i--){
            heapify(nums, i, heapSize);
        }
    }
    
    public void heapify(int[] nums, int i, int heapSize){
        int leftChild = 2 * i + 1;
        int rightChild = 2 * i + 2;
        int maxIndex = i;
        if (leftChild < heapSize && nums[leftChild] > nums[maxIndex]){
            maxIndex = leftChild;
        }
        if (rightChild < heapSize && nums[rightChild] > nums[maxIndex]){
            maxIndex = rightChild;
        }
    
        if (maxIndex != i){
            swap(nums, maxIndex, i);
            heapify(nums, maxIndex, heapSize);
        }
    }
    
    public void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    

    补充:堆排序(leetcode 912)

    代码如下:

    public void heapSort(int[] nums) {
        int heapSize = nums.length;
        buildMaxHeap(nums, heapSize);
        for (int i = nums.length - 1; i >= 0; i--){
            swap(nums, 0, i);
            heapSize--;
            heapify(nums, 0, heapSize);
        }
        
    }
    
    public void buildMaxHeap(int[] nums, int heapSize){
        for (int i = (heapSize - 1) / 2; i >= 0; i--){
            heapify(nums, i, heapSize);
        }
    }
    
    public void heapify(int[] nums, int i, int heapSize){
        int leftChild = 2 * i + 1;
        int rightChild = 2 * i + 2;
        int maxIndex = i;
        if (leftChild < heapSize && nums[leftChild] > nums[maxIndex]){
            maxIndex = leftChild;
        }
        if (rightChild < heapSize && nums[rightChild] > nums[maxIndex]){
            maxIndex = rightChild;
        }
    
        if (maxIndex != i){
            swap(nums, maxIndex, i);
            heapify(nums, maxIndex, heapSize);
        }
    }
    
    public void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    
    
    public int[] sortArray(int[] nums) {
        heapSort(nums);
        return nums;
    }
    
  • 相关阅读:
    读胶料温度代码
    干掉win10自带的不给力的应用(转自https://jingyan.baidu.com/article/08b6a591b7398514a8092238.html)
    安装SQL提示重启电脑失败,解决办法
    几种加解密方法:AES、DES、SHA数据加密
    SQL数据库添加新账号,只操作指定数据库
    jQuery中attr()、prop()、data()用法及区别
    jquery.cookie() 的使用(原)
    功能强大的web打印控件lodop的使用
    Win+R命令大全
    Vue
  • 原文地址:https://www.cnblogs.com/swifthao/p/13471593.html
Copyright © 2011-2022 走看看