標籤:歸併排序 java
思想:
假設初始序列右n個記錄,首先將這n個記錄看成n個有序的子序列,每個子序列的長度為1,然後兩兩歸併,得到n/2向上取整 個長度為2(n為奇數時,最後一個序列的長度為1)的有序子序列。在此基礎上,在對長度為2的有序子序列進行兩兩歸併,得到若干個長度為4的有序子序列。如此重複,直至得到一個長度為n的有序序列為止。
穩定性:穩定
時間複雜度計算:
數組的大小是2的冪,這樣分下去始終可以被2整除。假設為2的k次方,即k=log2(n)。
每次我們選擇的值剛好是中間值,這樣,數組才可以被等分。
第一層遞迴,需要迴圈n次才能排序好,第二層迴圈2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以演算法複雜度為O(log2(n)*n) 。
代碼:
public static void sort(int[] data, int left, int right) { System.out.println(left+":"+right); if (left < right) { int center = (left + right) / 2; System.out.println(left+":"+center+":"+right); // 對左邊數組進行遞迴 sort(data, left, center); System.out.println(left+":"+center+":"+right); // 對右邊數組進行遞迴 sort(data, center + 1, right); // 合并 merge(data, left, center, right); } } public static void merge(int[] data, int left, int center, int right) { int[] tmpArr = new int[data.length]; int mid = center + 1; // third記錄中間數組的索引 int third = left; int tmp = left; while (left <= center && mid <= right) { // 從兩個數組中取出最小的放入中間數組 if (data[left] <= data[mid]) { tmpArr[third++] = data[left++]; } else { tmpArr[third++] = data[mid++]; } } // 剩餘部分依次放入中間數組 while (mid <= right) { tmpArr[third++] = data[mid++]; } while (left <= center) { tmpArr[third++] = data[left++]; } // 將中間數組中的內容複寫回原數組 while (tmp <= right) { data[tmp] = tmpArr[tmp++]; } System.out.println(Arrays.toString(data)); } public static void main(String[] args) { int[] a1 = {5,1,3,4,2}; sort(a1,0,a1.length-1); }
資料結構歸併排序java實現