归并排序 java_Java实现归并排序
歸并排序 (merge sort) 是一類與插入排序、交換排序、選擇排序不同的另一種排序方法。歸并的含義是將兩個或兩個以上的有序表合并成一個新的有序表。歸并排序有多路歸并排序、兩路歸并排序 , 可用于內(nèi)排序,也可以用于外排序。這里僅對內(nèi)排序的兩路歸并方法進行討論。
一、兩路歸并排序算法思路
分而治之(divide - conquer);每個遞歸過程涉及三個步驟
第一, 分解: 把待排序的 n 個元素的序列分解成兩個子序列, 每個子序列包括 n/2 個元素.
第二, 治理: 對每個子序列分別調(diào)用歸并排序MergeSort, 進行遞歸操作
第三, 合并: 合并兩個排好序的子序列,生成排序結(jié)果.
二、算法實現(xiàn)
此算法的實現(xiàn)不像圖示那樣簡單,現(xiàn)分三步來討論。首先從宏觀上分析,首先讓子表表長 L=1 進行處理;不斷地使 L=2*L ,進行子表處理,直到 L>=n 為止,把這一過程寫成一個主體框架函數(shù) mergesort 。然后對于某確定的子表表長 L ,將 n 個記錄分成若干組子表,兩兩歸并,這里顯然要循環(huán)若干次,把這一步寫成一個函數(shù) mergepass ,可由 mergesort 調(diào)用。最后再看每一組(一對)子表的歸并,其原理是相同的,只是子表表長不同,換句話說,是子表的首記錄號與尾記錄號不同,把這個歸并操作作為核心算法寫成函數(shù) merge ,由 mergepass 來調(diào)用。假設(shè)我們有一個沒有排好序的序列,那么首先我們使用分割的辦法將這個序列分割成一個一個已經(jīng)排好序的子序列,然后再利用歸并的方法將一個個的子序列合并成排序好的序列。分割和歸并的過程可以看下面的圖例。
三、代碼實現(xiàn)
public static int[] sort(int[] a,int low,int high){
int mid = (low+high)/2;
if(low
sort(a,low,mid);
sort(a,mid+1,high);
//左右歸并
merge(a,low,mid,high);
}
return a;
}
public static void merge(int[] a, int low, int mid, int high) {
int[] temp = new int[high-low+1];
int i= low;
int j = mid+1;
int k=0;
//?把較小的數(shù)先移到新數(shù)組中
while(i<=mid && j<=high){
if(a[i]
temp[k++] = a[i++];
}else{
temp[k++] = a[j++];
}
}
//?把左邊剩余的數(shù)移入數(shù)組
while(i<=mid){
temp[k++] = a[i++];
}
//?把右邊邊剩余的數(shù)移入數(shù)組
while(j<=high){
temp[k++] = a[j++];
}
//?把新數(shù)組中的數(shù)覆蓋nums數(shù)組
for(int x=0;x
a[x+low] = temp[x];
}
}
四、算法分析
(1)穩(wěn)定性
歸并排序是一種穩(wěn)定的排序。
(2)存儲結(jié)構(gòu)要求
可用順序存儲結(jié)構(gòu)。也易于在鏈表上實現(xiàn)。
(3)時間復(fù)雜度
對長度為n的文件,需進行趟二路歸并,每趟歸并的時間為O(n),故其時間復(fù)雜度無論是在最好情況下還是在最壞情況下均是O(nlgn)。
(4)空間復(fù)雜度
需要一個輔助向量來暫存兩有序子文件歸并的結(jié)果,故其輔助空間復(fù)雜度為O(n),顯然它不是就地排序。
注意:
若用單鏈表做存儲結(jié)構(gòu),很容易給出就地的歸并排序
總結(jié)
以上是生活随笔為你收集整理的归并排序 java_Java实现归并排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2018程序员最佳ssh免费登陆工具
- 下一篇: Java编码规范,在您进行编码之前应该阅