總結
歸并排序主要用了分治的思想,通過將數組分成較小的段,對小段進行排序然后將小段合并起來,從而完成排序。歸并排序的時間復雜度是O(nlgn),可以證明nlgn是所有基于比較的算法效率的上限
在看書的過程中,發現自己的代碼風格太幼稚,例如:我寫 a[i] = aru[j];j++;而在算法書上只要一句 a[i] = a[j++];就搞定了。原因可能是自己在這方面沒有思考,老是覺得把功能寫好就行了,對這些用法沒有深入的理解。
例如for循環中,第一項用于聲明變量,第二項是個布爾表達式,在第二項可以進行一些除邊界判斷的判斷,第三項是每個循環完成后的操作,利用這些特性可以使自己的代碼更加簡潔。
merge歸并數組的函數
/*
* 原地歸并的抽象方法,用于將兩個相臨、有序的序列歸并
*/
public static void merge(Comparable[] a,int lo,int mid,int hi){
int i = lo,j = mid+1;
for(int k=lo;k<=hi;k++) aux[k] = a[k];//將傳入的數組復制
for(int k=lo;k<=hi;k++){
if(less(aux[j],aux[i])) a[k]=aux[j++];
else if (i>mid) a[k]=aux[j++];
else if(j>hi) a[k]=aux[i++];
else a[k]=aux[i++];
}
自頂向下的歸并排序
主要思想:利用遞歸的方法分解,歸并
/*
* 自頂向下的歸并排序
* 基本思想:分治法,將數組分為較小的快排序再合并
*/
public static void mergeSort(Comparable[] a){
aux = new Comparable[a.length];
int lo = 0,hi = a.length;
mergeSort(a, lo, hi);
}
/*
* 分解、合并數組
*/
public static void mergeSort(Comparable[] a,int lo,int hi){
if(hi<=lo) return;
int mid =lo + (hi-lo)/2-1;
mergeSort(a, lo, mid);
mergeSort(a, mid, hi);
merge(a,lo,mid,hi);
}
自底向上的歸并排序
主要思想:先將數組分解再歸并
/*
* 自底向上的歸并排序
* 基本思想:分治法,先將數組分為小塊再合并
*/
public static void bottomMergeSort(Comparable[] a){
int N = a.length;
aux = new Comparable[a.length];
for(int sz = 1;sz<N;sz+=sz)//控制要歸并數組的大小
for(int lo = 0;lo<N-sz;lo+=sz+sz)//控制歸并數組的索引
merge(a,lo,lo+sz-1,Math.min(lo+sz+sz-1,N-1));
}