歸併排序:採用分治法的思想(遞歸),將整個數組序列分成兩個序列,再講兩個序列分成各自的子序列,採用遞歸的思想解決一個個的子問題。
歸併排序的時間複雜度:O(n*lgn)
歸病排序的空間複雜度:O(n)
歸併排序的兩個核心:
核心一:將兩個有序序列合併。比較兩個數列的第一個數,誰小就取誰,然後讓該數列向後移動一位,知道其中的一個序列移動到最後一個,將另一個序列按照次序加入到已排到的序列後面。
核心二:將數組的兩部分變爲有序序列。將數組分成A、B組,各自再分成兩個子組,當分出來的小組只有一個數據時,可以認爲這個小組的組內已經達到有序,將這兩個組合並。這樣先遞歸分解數列在合併數列就完成了歸併排序。
java代碼:
public class MermeSort {
//將兩個有序序列進行合併
public static void mermeArray(int[] arrs,int first, int mid, int last, int[] temp){
int f = first;
int m = mid;
int n = mid + 1;
int l = last;
int k = 0;
//將一個有序序列歸併完成
while(f <= m && n <= l){
if(arrs[f] < arrs[n]){
temp[k++] = arrs[f++];
}else{
temp[k++] = arrs[n++];
}
}
//如果剩下左邊的序列,則將左邊的序列依次添加到temp後面
while(f <= m){
temp[k++] = arrs[f++];
}
//如果剩下的是右邊的序列,則將右邊的序列添加到temp後面
while(n <= last){
temp[k++] = arrs[n++];
}
//將temp中的有序序列依次拷貝到arrs序列相應的位置(first到last之間的這段序列)
for (int i = 0; i < k; i++) {
arrs[first+i] = temp[i];
}
}
public static void mermeSort(int[] arrs, int first, int last, int[] temp){
if(first < last){
int mid = (first + last) / 2;
mermeSort(arrs,first,mid,temp);//對first--last的前一半的元素進行排序
mermeSort(arrs, mid+1, last, temp);//對first--last的後一半的元素進行排序
mermeArray(arrs,first,mid,last,temp);//對first--last左右兩邊拍好的兩個序列進行歸併
}
}
}
很多人看了遞歸,很懵逼,我靜下心來分析了一遍,並畫出如下圖: