• 读书日记- 堆排序算法


    堆排序

      不仅在排序上有较好的时间复杂度,同时最大堆,最小堆在解决top10等问题上有很好的效果。

    最大堆性质,除了根以为的所有结点i都要满足:

      A[parent(i)]>=A[i]

    即,子节点一定小于等于父节点,且任意子树也满足该性质。

    Max-Heapify是维持最大堆性质的关键。时间复杂度O(lgn).

    #define LEFT(a)  ((a)*2+1)
    #define RIGHT(a)  ((a)*2+2)
    void ExChange(int& a,int& b)
    {
         a=a^b;  
         b=a^b;  
         a=a^b;
    }
    void Max_Heapify(int* intArr,int i,int length)
    {      
        int l = LEFT(i);
        int r = RIGHT(i);
    
        int largest = i;
        if (l< length && intArr[l] >intArr[largest])
        {
            largest = l;
        }
        if (r< length && intArr[r] >intArr[largest])
        {
            largest = r;
        }
    
        if(largest!=i)
        {
            ExChange(intArr[i],intArr[largest]); 
            Max_Heapify(intArr,largest,length);
        }
    }

    通过Max_Heapify可以使root不符合性质递归保持最大堆的性质。

    如下:

                        16

           4              10

            14       7       9       3

            2     8   1

            (a)

                         16

          14              10

             4        7     9       3

            2     8   1

            (b)

                      16

         14          10

            8     7       9    3

            2     4    1

            (c)

    建堆:

      通过自底向上的方法调用Max_Heapify,即可把一个数组转换为最大堆。

      

    void Build_Max_Heap(int* intArr,int length)
    {
        for(int i=length/2+1;i>=0;i--)
        {
            Max_Heapify(intArr, i,length);
        }
    }

    排序:

        在有了一个最大堆后,通过不断取出最大值,并对剩余的值进行Max_Heapify即可保持最大堆性质,始终从根节点取得当前最大值,从而实现排序。

    代码如下:

    void Heap_Sort(int* intArr,int length)
    {
        Build_Max_Heap(intArr,length);
        for(int i= length-1;i>0;i--)
        {
            ExChange(intArr[0],intArr[i]);
            Max_Heapify(intArr,0,--length);
        }
    }

     

    因为每次Max_Heapify时间为O(logn),所以堆排序时间为O(nlogn)

  • 相关阅读:
    算法分析(3)——冒泡排序真的慢吗?
    算法分析(2)——大O和大Θ
    算法分析(1)——数据的影响和函数的增长
    递归的逻辑(5)——米诺斯的迷宫
    递归的逻辑(4)——递归与分形
    李洪强和你一起学习前端之(9)规避脱标,CSS可见性,滑动门案例
    iOS应用管理(优化)
    iOS开发-应用管理
    iOS开发-Tom猫
    iOS 10.3.3 更新背后的故事
  • 原文地址:https://www.cnblogs.com/stratrail/p/5040472.html
Copyright © 2020-2023  润新知