堆排序算法

    技术2024-07-15  64

    对排序可分为两个部分:1.将待排序的数据调整成最大堆或者最小堆 需要比较n-1趟(假设有n个数据)耗时O(n)

                                     2.从最大堆中选择最大或最小的元素只需比较二叉树深度logn的次数

        因此该算法的时间复杂度为O(N*log n)

     

     

    第一部分也即为调整树的过程,参考代码如下:

    //R[]为带调整的数组,s为要调整元素的开始下标,m为结束元素下标 

    void HeapAdjust( Elem R[], int  s, int m)

    {

     

        rc = R[s];   

        for( j= 2* s; j < m ; j *=2 )    //2s为元素s的左子树

             {

     

                 if( j<m  && R[j].key < R [j+1].key )  j++;     //左子树小于右子树 j自加,定位到右子树

                

                 if(rc .key >=R [j].key )  break ;     //rc大于孩子节点的最大值 ,跳出循环

                 R[s]=R[j] ;   //rc小于孩子节点最大值,将最大值赋给R[S]

                 s=j ;    //将此时j的值赋给s,如果还满足上面的条件,则还需调整,直到成为最大堆

     

            }

     

          R[s] =rc ;   //将开始时候的R[s]的值赋给现在的R[s],注意现在的s值已发生了变化

     

    }

     

     

     

    //下面是堆排序的过程,将第一个元素,也就是树的根节点元素与最后一个元素交换,在从新调整成最大堆,但已调整过的元素不参与

    void HeapSort(Elem R[], int n)  //n为数据元素的个数

    {

     

       for ( i = n/2 ; i > 0 ; i -- )

               HeapAdjust(R,i ,n) ;   //调整成最大堆

        for( i> n ; i> 1;i--)

            {

     

     

             R[1]  <--->R[i];   //堆顶与最后一个元素交换

                 HeapAdjust( R,1,i-1);  //从第一个到最后一个元素重新调整成最大堆

     

     

         }

       

     

     

    }

     

    最新回复(0)