歸併排序基本思想:java
將原數組從中間分開,分紅兩個子數組,而後繼續將子數組從中間分開,直到把全部子數組分解到只有數組
一個元素,此時分的過程就結束了code
而後開始治,遞歸回退一層,將兩個子數組合併成一個新的有序的數組,而後依次回退與其它子數組合併成blog
新的數組,直到合併成原始數組排序
歸併排序基本思想示意圖1:遞歸
歸併排序基本思想示意圖2:索引
public static void mergeSort(int[] arr, int left, int right, int[] temp) { if (left < right) { int mid = (left + right) / 2;//中間索引,今後處將數組劃分紅兩份 //向左遞歸進行分解 mergeSort(arr, left, mid, temp); //向右遞歸進行分解 mergeSort(arr, mid + 1, right, temp); //當分解到只有兩個元素的數組時,就開始排序合併 merge(arr,left,mid,right,temp); } //只有一個元素了,就不能合併,則回退一層,再合併 } /** *@param arr 排序的原始數組 * @param left A有序數組的起始索引 * @param mid 中間索引,也就是A數組的最後一個索引 * @param right B數組的終止索引 * @param temp 合併的數組 */ public static void merge(int[] arr, int left, int mid, int right, int[] temp) { int i = left;//左邊有序序列的初始索引 int j = mid + 1;//右邊有序序列的初始索引 int t = 0;//t指向temp數組的當前索引 //(一) //先把左右兩邊(有序)的數據按規則填充到temp數組 //直到左右兩邊有一邊遍歷結束 while (i <= mid && j <= right) { //比較兩數組中當前索引的數,哪一個小就加入到temp if (arr[i] <= arr[j]) { temp[t++] = arr[i++]; } else { temp[t++] = arr[j++]; } } //(二) //將沒有遍歷完的數組的剩餘元素依次所有填充到temp數組 //由於若是當前數組還有剩餘,就說明另一個數組已經遍歷完成了 while (j <= right) { temp[t++] = arr[j++]; } while (i <= mid) { temp[t++] = arr[i++]; } t = 0; //(三) //將temp數組的元素拷貝到arr //第一次合併是 left=0,right=1 left=2,right=3 //第二次合併是 left=0,right=3 //最後合併是 left=0,right=7 for (int k = left; k <= right; k++) { arr[k] = temp[t++]; } }