首先 解釋一下什麼是歸併排序的精髓就是把一個亂序數組劃分成小的數組來排序,然後再把小的數組合併成大的小組,下面的這張圖能夠明確說明什麼是歸併排序
雖然看圖感覺二路歸併排序很簡單,但是實際操作起來還是有一點麻煩的
這是主函數
public static void main(String[] args) {
int[] array = new int[] { 10, 9, 5, 11, 45, 23, 2, 13 };
splitArray(array, 0, array.length - 1);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
private static void sort(int[] array, int left, int mid, int right) {
int[] leftArray = new int[mid-left];//第一個數組的長度
int[] rightArray = new int[right - mid + 1];//第二個數組的長度
int i = 0, j = 0, k = 0;
for (i = left; i < mid; i++)//將最傳進來大的數組分成兩個小的數組,分別爲LeftArray與RightArray
leftArray[i - left] = array[i];
for (i = mid; i <= right; i++)
rightArray[i - mid] = array[i];
i = 0;
j = 0;
k = left;
while (i < mid - left && j < right - mid + 1) {//任意一個不滿足條件即可退出
/*
* 這裏就是把兩個數組有序的合在一起的精髓,將第一個數組的第一個元素與第二個數組的第一個元素相比較,如果第一個數組的元素是小的就講這個值複製給最大的數組的第一位
* 然後最大數組與複製給最大數組的數組下標都自加
*/
if (leftArray[i] < rightArray[j]) {
array[k++] = leftArray[i++];
} else {
array[k++] = rightArray[j++];
}
}
/*
* 上面的while循環跳出 檢查將後面的沒有排完的值全部加給最大的數組
*/
while (i < mid - left) {
array[k++] = leftArray[i++];
}
while (j < right - mid + 1) {
array[k++] = rightArray[j++];
}
}
這裏就是合併了,把兩個數組合併爲一個數組
然後我們看最爲核心的東西
private static void splitArray(int[] array, int left, int right) {
if (left == right) {
return;
} else {
int mid = (right + left) >> 1;//得到中間值
splitArray(array, left, mid);//處理左邊的數組
splitArray(array, mid+1, right);//處理右邊的數組
sort(array, left, mid+1 , right);//歸併
}
}
在這裏將傳遞進來的左邊與右邊分別是最大數組的最大下標與最小下標,將他們除2 我們就可以得到他的中間值,然後遞歸第一個遞歸是處理左邊的數組將左邊的數組分割,第二個遞歸是處理右邊的遞歸,第三個遞歸就是調用第二個sort函數將他們排序並且組合在一起
也許在三個遞歸你會感覺到理解有點困難,我們來debug 調試一下你就會發現他的規律了
End!!!!