一、動圖演示
二、思路分析
歸並排序就是遞歸得將原始數組遞歸對半分隔,直到不能再分(只剩下一個元素)后,開始從最小的數組向上歸並排序
1. 向上歸並排序的時候,需要一個暫存數組用來排序,
2. 將待合並的兩個數組,從第一位開始比較,小的放到暫存數組,指針向后移,
3. 直到一個數組空,這時,不用判斷哪個數組空了,直接將兩個數組剩下的元素追加到暫存數組里,
4. 再將暫存數組排序后的元素放到原數組里,兩個數組合成一個,這一趟結束。
根據思路分析,每一趟的執行流程如下圖所示:
三、負雜度分析
1. 時間復雜度:遞歸算法的時間復雜度公式:T[n] = aT[n/b] + f(n)
無論原始數組是否是有序的,都要遞歸分隔並向上歸並排序,所以時間復雜度始終是O(nlog2n)
2. 空間復雜度:
每次兩個數組進行歸並排序的時候,都會利用一個長度為n的數組作為輔助數組用於保存合並序列,所以空間復雜度為O(n)
四、Java 代碼如下
import java.util.Arrays; public class Main { public static void main(String[] args) { int[] arr = new int[]{3,6,4,7,5,2}; merge(arr,0,arr.length-1); System.out.println(Arrays.toString(arr)); } //歸並
public static void merge(int[] arr,int low,int high){ int center = (high+low)/2; if(low<high){ //遞歸,直到low==high,也就是數組已不能再分了,
merge(arr,low,center); merge(arr,center+1,high); //當數組不能再分,開始歸並排序
mergeSort(arr,low,center,high); System.out.println(Arrays.toString(arr)); } } //排序
public static void mergeSort(int[] arr,int low,int center,int high){ //用於暫存排序后的數組的臨時數組
int[] tempArr = new int[arr.length]; int i = low,j = center+1; //臨時數組的下標
int index = 0; //循環遍歷兩個數組的數字,將小的插入到臨時數組里
while(i<=center && j<= high){ //左邊數組的數小,插入到新數組
if(arr[i]<arr[j]){ tempArr[index] = arr[i]; i++; }else{//右邊數組的數小,插入到新數組
tempArr[index] = arr[j]; j++; } index++; } //處理左半邊數組多余的數據,將左半邊多余的數據直接追加的臨時數組的后面
while(i<=center){ tempArr[index] = arr[i]; i++; index++; } //處理右半邊數組多余的數據,將右半邊多余的數據直接追加的臨時數組的后面
while(j<= high){ tempArr[index] = arr[j]; j++; index++; } //將臨時數組中的數據重新放進原數組
for (int k = 0; k < index; k++) { arr[k+low] = tempArr[k]; } } }