zoukankan      html  css  js  c++  java
  • 最大堆构建和堆排序

    1 输入一个任意长度的无规律数组,把该数组构建为最大堆

    2 用构建好的最大堆,进行堆排序

     1 public class Solution {
     2     
     3     /**
     4      * 构建堆
     5      * @param array
     6      */
     7     public static void buildMaxHeap(int[] array) {
     8         
     9     /*    for (int i = array.length / 2; i >= 0; i--) {
    10             adjust(array, i, array.length);    
    11         }*/
    12         /** 以树的最后一个节点的父节点为根开始调整  */
    13         int last = array.length - 1;
    14         int pos = (last - 1) / 2;
    15         while (pos >= 0) {
    16             adjust(array, pos--, array.length);
    17         }
    18     }
    19     
    20     
    21     /**
    22      * 把以root为根的那棵子树调整为最大堆, 此时以root为根的左右子树都以调整为最大堆
    23      * @param array
    24      * @param root
    25      * @param len
    26      */
    27     public static void adjust(int[] array, int root, int len) {
    28         int l = root * 2 + 1;
    29         int r = root * 2 + 2;
    30         int largest = root;
    31         
    32         /** 特别要考虑满二叉树的情况 */
    33         //parent节点有左孩子
    34         if (l < len && array[l] > array[largest]) {
    35                 largest = l;
    36         }
    37         //parent节点有右孩子
    38         if (r < len && array[r] > array[largest]) {
    39                 largest = r;
    40         }
    41         
    42         //如果以root为根的堆
    43         if (largest != root) {
    44             swap(array, root, largest);
    45             adjust(array, largest, len);
    46         }
    47     }
    48     
    49     
    50     /**
    51      *  堆排序函数
    52      * @param array
    53      * @param len
    54      */
    55     public static void heapSort(int[] array) {
    56         
    57         int len = array.length;
    58         
    59         while (len > 1) {
    60             /** 堆顶的元素为数组中所有元素的最大值
    61                                 出堆顶,把堆对应树的最后那个节点放到堆顶(从堆顶向下调整)
    62                                 此时,堆对应树的最后那个节点位置为空,把刚出的堆顶最大值放入该空位 */
    63             swap(array, 0, len - 1); //拿堆对应的树的最后一个节点与根节点交换
    64             len--;
    65             adjust(array, 0, len);
    66         }
    67     }
    68     
    69     public static void print(int[] array) {
    70         for (int i = 0; i < array.length;  i++) {
    71             System.out.println(i + ", " + array[i]);
    72         }
    73     }
    74     
    75     public static void swap(int[] array, int t1, int t2) {
    76         int temp = array[t1];
    77         array[t1] = array[t2];
    78         array[t2] = temp;
    79     }
    80     
    81     
    82     
    83     public static void main(String[] args) {
    84         
    85         //生成随机数数组
    86         int[] array = { 53, 17, 78, 9, 45, 65, 87};
    87         
    88         buildMaxHeap(array);
    89         System.out.println("建堆完成:");
    90         print(array);
    91         System.out.println("------------------");
    92         
    93         heapSort(array);
    94         print(array);
    95     }
    96 }

     上述方案调整堆的原理为:

        1)叶子节点,无子树,可以把叶结点看作为一棵树,为最大堆

        2)从最后一个叶节点开始

        3)让pos指向该叶结点的父节点,pos指向一个子树,其孩子(为叶结点)已是最大堆,然后我们只要把这棵树调整为最大堆

        4)pos减1,走3),直到pos指向数组索引0处,把堆顶调整完成

  • 相关阅读:
    hadoop分片分析
    hadoop输入分片计算(Map Task个数的确定)
    hadoop运行原理之Job运行(五) 任务调度
    hadoop运行原理之Job运行(四) JobTracker端心跳机制分析
    BlockTransferService 实现
    spark 持久化机制
    spark DiskBlockManager
    spark checkpoint机制
    hadoop InputFormat getSplits
    hadoop LineRecordReader
  • 原文地址:https://www.cnblogs.com/asnjudy/p/5701668.html
Copyright © 2011-2022 走看看