• 排序算法----堆排序


    堆排序算法使用二叉堆实现排序,树上的每一个节点对应数组中的一个元素。

    第一步:使用MAX_HEAPIFY维护一个最大堆(所有孩子节点都必须小于或等于其父节点)。它的输入为一个数组A和一下标i,调用MAX_HEAPIFY时,假设节点i的左右子树都是最大堆。

    伪码:

     1 LEFT(i)
     2   return 2i
     3 
     4 RIGHT(i)
     5   return 2i+1
     6 
     7 MAX_HEAPIFY(A,i)
     8   
     9 l = LEFT(i)
    10 
    11 r = RIGHT(i)
    12 
    13 if l <=A.heap-size and A[l] > A[i]
    14 
    15     largest = l
    16 
    17 else
    18 
    19     largest = i
    20 
    21 if r<= A.heap-size and A[r] > A[largest]
    22 
    23    largest = r
    24 
    25 if largest != i
    26 
    27     exchange A[i] with A[largest]
    28 
    29    MAX_HEAPIF(A,largest)
    View Code

     假设节点i的左子数和右子数都是最大堆。程序首先找出节点i,它的左孩子节点和右孩子节点中最大的一个,如节点i是最大,那么以i为根节点二叉堆就是最大堆了程序结束;否则,交换节点i和最大那个节点largest,于是以largest为根节点的二叉树就有可能违反了最大堆的性质,因此以largest为下标递归调用MAX_HEAPIFY。

    第二步:使用BUILD_MAX_HEAP(A)建立一个最大堆。

    伪码:

    1 BUILD-MAX_HEAP(A)
    2 
    3 A.heap-size = A.length
    4 
    5 for i = ⌊A.length / 2⌋   downto 1
    6 
    7    MAX_HEAPIFY(A,i) 
    View Code

    从底向上的方法利用MAX_HEAPIFY把长度为n的数组A转换为一个最大堆。这里我们不用从数组A的最后一个元素开始调用MAX_HEAPIFY,可以证明:从⌊n/2⌋ + 1 到n中的元素都是数的叶节点(没有孩子节点),所以我们从⌊n/2⌋到1调用MAX_HEAPIFY,转换A成为一个最大堆.

    第三步:使用BUILD_MAX_HEAP 和 MAX_HEAPIFY完成堆排序算法HEAPSORT

    伪码:

     1 HEAPSORT(A)
     2 
     3 BUILD-MAX-HEAP(A)
     4 
     5 for i = A.length downto 2
     6 
     7     exchange A[1]  with A[i]
     8 
     9     A.heap-size = A.heap-size - 1
    10 
    11    MAX-HEAPIFY(A,1)
    View Code

     首先:利用BUILD_MAX_HEAP 把传入的数组A转换为一个最大堆,在最大堆中,根节点为所有节点中最大的;

     然后:交换二叉堆根节点A[1]和最后一个节点A[n],这时数组中的最大的值被交换到数组的最后;把最后一个节点从堆中去掉,利用MAX_HEAPIFY从新维护数组A[1],A[n -1]为一个最大堆

      最后:循环上面步骤,把依次最大的值放到数组末尾,直到堆的大小降到2

    时间复杂度:HEAPSORT过程的时间复杂度是O(nlgn),每次调用BUILD_MAX_HEAP的时间复杂度是O(n),n-1次调用MAX_HEAPIFY,每次时间为O(lgn);

    C++代码:

     1 #define   LEFT(i)   (2 * (i + 1) - 1)
     2 #define   RIGHT(i)  (2 * (i + 1))
     3 
     4 #define   EXCHANGE(a,b) (a) = (a) + (b);
     5                                         (b) = (a) - (b);
     6                                         (a) = (a) - (b)
     7 
     8 void MAX_HEAPIFY(int A[],int i,int heap_size)
     9 {
    10     int l = LEFT(i);
    11     int r = RIGHT(i);
    12     int largest = -1;
    13 
    14     if(l <= heap_size && A[l] > A[i])
    15     {
    16         largest = l;
    17     }
    18     else
    19     {
    20         largest = i;
    21     }
    22 
    23     if(r <= heap_size && A[r] > A[largest])
    24     {
    25         largest = r;
    26     }
    27 
    28     if(largest != i)
    29     {
    30         EXCHANGE(A[i],A[largest]);
    31         MAX_HEAPIFY(A,largest,heap_size);
    32     }
    33 }
    34 
    35 void BUILD_MAX_HEAP(int A[],int heap_size)
    36 {
    37     for(int i = heap_size / 2;i >=0;--i)
    38     {
    39         MAX_HEAPIFY(A,i,heap_size);
    40     }
    41 }
    42 
    43 //堆排序,T(n) = O(nlgn) 
    44 void HEAPSORT(int A[],int heap_size)
    45 {
    46     BUILD_MAX_HEAP(A,heap_size);
    47     for(int i = heap_size;i > 0;--i)
    48     {
    49         EXCHANGE(A[heap_size],A[0]);
    50         heap_size -= 1;
    51         MAX_HEAPIFY(A,0,heap_size);
    52     }
    53 }
    View Code
  • 相关阅读:
    JavaScript与ajax的作用域问题
    Note
    理解C#反射
    秋季雾天驾驶注意安全
    开车撞车之后
    医保机构电话
    提前还贷四大细节需要注意
    请在这汽车内循环和外循环正确使用方法!你会用了吗?
    老外吐槽“娶中国老婆等于娶一家人”引共鸣
    车型与车主
  • 原文地址:https://www.cnblogs.com/jx-dx/p/3756248.html
Copyright © 2020-2023  润新知