算法設計與分析——自然合並排序(分治法)


算法的C++實現以及基本思想的圖解說明,參考我之前的博客

https://www.cnblogs.com/wkfvawl/p/9772447.html

 

 

合並排序是利用分治策略對n個元素進行排序的算法,其基本思想是:將待排序元素分為大小大致相同的2個子集合,分別對這兩個子集合進行排序,最終將排序好的子集合合並為所要求的的排好序的集合,遞歸寫法如下:

    public static void mergeSort(Comparable []a,int left,int right)
    {
        if(left<right)
        {
            int mid = (left + right) / 2;      //取中點
            mergeSort(a,left,mid);             //左合並排序
            mergeSort(a,mid+1,right);          //右合並排序
            merge(a,b,left,right);             //合並到數組b
            copy(a,b,left,right);              //復制回數組a
        }
    }

其中,算法merge合並2個排序好的數組段到新的數組b中,然后由算法copy將合並后的數組段再復制回數組a中。算法merge和copy顯然可以早O (n)時間內完成,因此對n個元素進行排序,最壞情況下所需要計算的時間T(n)滿足

 

解此遞歸方程可知 T(n) = O(nlogn)。

 

 

按照此思想,消去遞歸后的合並排序可以描述為:

public static void mergeSort(Comparable []a)
    {
        Comparable []b = new Comparable[a.length];
        int s=1;
        while(s<a.length)
        {
            mergePass(a,b,s);          //合並到數組b
            s+=s;
            mergePass(b,a,s);          //合並回數組a
            s+=s;
        }
    }

其中,算法mergePass用於合並排好的相鄰數組段。具體的合並算法由merge來實現。

public static void mergePass(Comparable []x,Comparable []y,int s)
    {
        int i=0;
        while(i<=x.length-2*s)
        {
            merge(x,y,i,i+s-1,i+2*s-1);
            i=i+2*s;
        }
        if(i+s<x.length)            //剩下的元素個數少於2s
        {
            merge(x,y,i,i+s-1,x.length-1);
        }
        else
        {
            //復制到y
            for(int j=i;j<x.length;j++)
            {
                y[j]=x[j];
            }
        }
    }

 

  public static void merge(Comparable[]c,Comparable[]d,int l,int m,int r)
    {
        int i=1;
        int j=m+1;
        int k=l;
        while((i<==m)&&(j<=r))
        {
            if(c[i].compareTo(c[j])<=0)  //c[i]<c[j]
            {
                d[k++]=c[i++];
            }
            else                         //c[i]>c[j]
            {
                d[k++]=c[j++]
            }
        }
        //將剩下的元素存到數組中
        while(i<=m)
        {
            d[k++]=c[i++];
        }
        while(j<=r)
        {
            d[k++]=c[j++];
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM