思路:
- 1、寫出遞推公式:merge_sort(p…r) = merge(merge_sort(p…q), merge_sort(q+1…r))
- 2、判斷終止條件:head >= tail
- 3、分治遞歸
- 4、排序後,合併兩個有序數組
總結:
- 1、總結時間複雜度爲O(nlogn)
- 2、是穩定的算法
- 3、是空間複雜度是O(n),不是原地排序算法。它會開闢新的內存空間所以用的比較少
直接上代碼:
/**
* 歸併排序
* Author : BlueSky 2019.11.07
*/
public class MergeSort {
public static void main(String[] args) {
int capacity = 9;
Integer[] arr = new Integer[capacity];
arr[0] = 4;
arr[1] = 1;
arr[2] = 7;
arr[3] = 3;
arr[4] = 0;
arr[5] = 5;
arr[6] = 6;
arr[7] = 2;
arr[8] = 8;
mergeSortMethod(arr,capacity);
System.out.println("==>final arr:"+Arrays.toString(arr));
}
public static void mergeSortMethod(Integer[] arr, int capacity){
sort(arr, 0, capacity-1);
}
public static void sort(Integer[] arr, int head, int tail){
if(head >= tail){
return;
}
int center = (head + tail)/2;
// 分治遞歸
sort(arr, head, center);
sort(arr, center + 1 ,tail);
// 將arrHead和arrTail合併到arr中
merge(arr, head, center, tail);
}
/**
* 合併
* arr:原始數組
* arrHead:左邊數組
* head:左邊數組左指針
* arrTail:右邊數組
* tail:右邊數組右指針
*/
public static void merge(Integer[] arr, int head, int center, int tail){
System.out.println("==>init arr:"+Arrays.toString(arr));
System.out.println("==>init head:"+head);
System.out.println("==>init center:"+center);
System.out.println("==>init tail:"+tail);
// 賦新的數組
final Integer[] arrHead = new Integer[center - head + 1 + 1];
for(int i = 0; i < center - head + 1; i++){
arrHead[i] = arr[head + i];
}
final Integer[] arrTail = new Integer[tail - center + 1];
for(int i = 0; i < tail - center; i++){
arrTail[i] = arr[center + i +1];
}
// 設置標誌位 避免下面賦值數組越界
Integer flag = Integer.MAX_VALUE;
arrHead[center - head + 1] = flag;
arrTail[tail - center ] = flag;
int i = 0;
int j = 0;
for(int k = head;k <= tail; k++){
if(arrHead[i] <= arrTail[j]){
arr[k] = arrHead[i];
i = i+1;
}else {
arr[k] = arrTail[j];
j = j+1;
}
}
System.out.println("==>賦值後的數組:"+Arrays.toString(arr));
}
}