歸併排序java
這是一種分治法的應用,就是對於一個待排序的序列,將它一分爲二,二分爲四……,分到最後,每個序列中只會包含一個元素,這時,每個小序列就已經有序了(由於只有一個元素,因此確定是有序的)。而後將其兩兩歸併排序,……四合爲二,二合爲一。這樣就能完排序功能。算法
該排序算法有兩個方法:數組
1.合併方法merge(),合併一個在某一位置分開,兩邊子序列分別有序的序列。code
2.歸併排序方法mergeSort(),這個方法遞歸調用,完成序列的拆分排序。
排序
/** * @Description 合併排序一個在startIndex到minIndex位置有序,且在midIndex到endIndex上有序的序列 * @param srcArray * 源數組,且該數組在startIndex到midIndex位置上有序,在midIndex到endIndex上有序 * @param targetArray * 目標數組,排序完成以後的數組,起始位置爲srcArray的起始位置 * @param startIndex * 排序開始位置 (不必定在srcArray的開始位置) * @param midIndex * 排序中間位置 * @param endIndex * 排序結束位置 * @return */ public static void merge(int[] srcArray, int[] targetArray, int startIndex, int midIndex, int endIndex) { // 注意目標數組的起始位置k是startIndex,而非0,由於srcArray的起始位置要和targetArray中的起始位置相同 int i = startIndex, j = midIndex + 1, k = startIndex; // 這裏i,j用來指示由srcArray拆分出的兩個有序子序列的起始位置 // 當某一個數組中的數字已經用完,那麼就不用再循環比較了,直接將另外一個數組中剩下的數字拼接到新數組中便可 while (i < midIndex + 1 && j < endIndex + 1) { if (srcArray[i] < srcArray[j]) { targetArray[k++] = srcArray[i++]; } else { targetArray[k++] = srcArray[j++]; } } // 若是startIndex到midIndex數組中還剩下有數,那麼將其拼接到目標數組targetArray中 while (i < midIndex + 1) { targetArray[k++] = srcArray[i++]; } // 若是midIndex到endIndex數組中還剩下有數,那麼將其拼接到目標數組targetArray中 while (j < endIndex + 1) { targetArray[k++] = srcArray[j++]; } } /** * @Description 歸併排序(遞歸),這個方法爲何須要一個開始位置和結束位置?由於這個數組在遞歸排序過程當中邏輯上會拆分紅不少小序列, * (一分爲二,二分爲四……) 直到一個序列只包含一個數爲止, * 而這個startIndex和endIndex則是指示這些邏輯上的小數組在源數組中的正確位置。 * @param srcArray * 待排序數組 * @param targetArray * 目標數組 * @param startIndex * 開始位置 * @param endIndex * 結束位置 * @return */ public static void mergeSort(int[] srcArray, int[] targetArray, int startIndex, int endIndex) { int midIndex; int[] tempArray = new int[1024]; // 該數組爲臨時數組,大小須要按照須要進行更改,必須>=源數組 // 特別注意:這是遞歸的出口,也就是指當序列一分爲二,二分爲四……,當序列被折分到子序列中只剩下一個元素的時候, // 那麼這個子序列就算是有序序列了(由於有一個元素,因此確定算是有序列的)。 // 將其直接存放於target目標數組中便可 if (startIndex == endIndex) { targetArray[startIndex] = srcArray[startIndex]; } else { midIndex = (startIndex + endIndex) / 2; mergeSort(srcArray, tempArray, startIndex, midIndex); // 遞歸排序左邊的序列 mergeSort(srcArray, tempArray, midIndex + 1, endIndex); // 遞歸排序右邊的序列 merge(tempArray, targetArray, startIndex, midIndex, endIndex); // 遞歸將排序好的序列(存放於temp中)進行2路歸併 } }