歸併排序非遞迴實現Java
阿新 • • 發佈:2018-12-23
遞迴實現的歸併排序,需要O(lgN)的棧空間,而非遞迴實現的歸併排序則不需要
原文地址:http://www.jianshu.com/p/39dd1d9b491d
public class Sort { public static void MergeSort2(int[] arr) { //使用非遞迴的方式來實現歸併排序 int len = arr.length; int k = 1; while(k < len) { MergePass(arr, k, len); k *= 2; } } //MergePass方法負責將陣列中的相鄰的有k個元素的字序列進行歸併 private static void MergePass(int[] arr, int k, int n) { int i = 0; int j; //從前往後,將2個長度為k的子序列合併為1個 while(i < n - 2*k + 1) { merge(arr, i, i + k-1, i + 2*k - 1); i += 2*k; } //這段程式碼保證了,將那些“落單的”長度不足兩兩merge的部分和前面merge起來。 if(i < n - k ) { merge(arr, i, i+k-1, n-1); } } //merge函式實際上是將兩個有序數組合併成一個有序陣列 //因為陣列有序,合併很簡單,只要維護幾個指標就可以了 private static void merge(int[] arr, int low, int mid, int high) { //temp陣列用於暫存合併的結果 int[] temp = new int[high - low + 1]; //左半邊的指標 int i = low; //右半邊的指標 int j = mid+1; //合併後陣列的指標 int k = 0; //將記錄由小到大地放進temp陣列 for(; i <= mid && j <= high; k++) { if(arr[i] < arr[j]) temp[k] = arr[i++]; else temp[k] = arr[j++]; } //接下來兩個while迴圈是為了將剩餘的(比另一邊多出來的個數)放到temp陣列中 while(i <= mid) temp[k++] = arr[i++]; while(j <= high) temp[k++] = arr[j++]; //將temp陣列中的元素寫入到待排陣列中 for(int l = 0; l < temp.length; l++) arr[low + l] = temp[l]; } }