算法的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++]; } }