使用歸併排序以下數組 [32, 12, 43, 5, 3, 8],使得排序後的結果爲: [3, 5, 8, 12, 32, 43]
解題須要如下兩個知識:java
一、歸併排序的核心思想是分治思想,就是把須要排序的規模分到最小,本題中是要分到什麼程度呢,也就是說分到每一個數組裏面只有一個元素,一個元素也就不用排了,就是這個元素自己數組
二、合併 兩個有序的數組合併成一個有序的數組,這也就是這個歸併排序名稱的由來,具體歸併的操做以下 兩個有序數組 a1=[1,3,5]和a2=[2,4,6] 合併以後是33=[1,2,3,4,5,6]。這裏面主要用到兩個指針,一個指向A1的開頭p1,一個指向A2的開頭p2,和一個空數組A3。而後比較a1[p1]和a2[p2]的大小,把小的放入到a3中,而後小的指針繼續往下走,直到其中的一個數組的元素都走完,而後把另一個數組的元素剩餘的部分所有放入到a3結尾處。圖例以下: 函數
/** * 歸併排序 * @param a 待排序的數組 */ public void mergeSort(int[] a) { int[] temp = new int[a.length]; mergeSortSub(a, temp, 0, a.length - 1); } /** * 須要用分治的代碼,其中left<right是跳出循環的條件。 * 分治以後調用merge函數對數組進行合併 * @param a 待排序的數組 * @param temp 臨時用來存放數組的數組 * @param left 分治之後的數組的左邊界 * @param right 分治以後數組的右邊界 */ public void mergeSortSub(int[] a, int[] temp, int left, int right) { if (left < right) { int center = (left + right) / 2; mergeSortSub(a, temp, left, center); mergeSortSub(a, temp, center + 1, right); merge(a, temp, left, center + 1, right); } } /** * 一個數組從中間分爲兩個有序數組,合併這兩個有序數組 * * @param a 待排序和合並的數組 * @param temp 合併和排序的結果 * @param leftPos 左邊有序數組起點 * @param rightPos 右邊有序數組的起點 * @param rightEnd 右邊的終點 */ public void merge(int[] a, int[] temp, int leftPos, int rightPos, int rightEnd) { int leftEnd = rightPos - 1; int tempPos = leftPos; int numElements = rightEnd - leftPos + 1; while (leftPos <= leftEnd && rightPos <= rightEnd) { int leftValue = a[leftPos]; int rightValue = a[rightPos]; if (leftValue > rightValue) { temp[tempPos] = rightValue; rightPos++; } else { temp[tempPos] = leftValue; leftPos++; } tempPos++; } while (leftPos <= leftEnd) { temp[tempPos] = a[leftPos]; leftPos++; tempPos++; } while (rightPos <= rightEnd) { temp[tempPos] = a[rightPos]; rightPos++; tempPos++; } for (int i = 0; i < numElements; i++, rightEnd--) { a[rightEnd] = temp[rightEnd]; } }
//測試代碼 @Test public void test_mergeSort() { int[] array = new int[]{32, 12, 43, 5, 3, 8}; int[] after = new int[]{3, 5, 8, 12, 32, 43}; mergeSort(array); Assert.assertArrayEquals(after, array); }
其中代碼的執行流程以下圖: 測試
O(NlogN)編碼
以上就是java實現歸併排序的全過程。最後再強調一遍,歸併排序的兩個關鍵點 分治和合併有序數組指針