【Java】 歸併排序的非遞迴實現 資料結構與演算法合集 資料結構與演算法合集
阿新 • • 發佈:2018-11-15
歸併排序可以採用遞迴方法(見:歸併排序),但遞迴方法會消耗深度位O(longn)的棧空間,使用歸併排序時,應該儘量使用非遞迴方法。本文實現了java版的非遞迴歸併排序。
更多:資料結構與演算法合集
思路分析
遞迴排序的核心是merge(int[] arr, int start, int mid, int end)函式,講[start~mid-1]和[mid~end]部分的資料合併,遞迴程式碼是使用遞迴得到mid,一步步分解陣列。
非遞迴時,我們直接定義要合併的小陣列長度從1開始,在較小的長度陣列都合併完成後,令長度*2,繼續進行合併,直到合併完成。
完整Java程式碼
(含測試程式碼)
public class MergeSort2 { public void mergeSort(int[] arr) { if(arr==null || arr.length<=0) return; int width = 1; while(width<arr.length) { mergePass(arr,width); width*=2; } } private void mergePass(int[] arr,int width) { int start=0; while(start+2*width-1<arr.length) { int mid=start+width-1; int end=start+2*width-1; merge(arr,start,mid,end); start=start+2*width; } //剩餘無法構成完整的兩組也要進行處理 if(start+width-1<arr.length) merge(arr, start, start+width-1, arr.length-1); } private void merge(int[] arr, int start, int mid, int end) { int i=start; int j=mid+1; int[] temp = new int[end-start+1]; int index=0; while(i<=mid && j<=end) { if(arr[i]<=arr[j]) temp[index++]=arr[i++]; else temp[index++]=arr[j++]; } while(i<=mid) temp[index++]=arr[i++]; while(j<=end) temp[index++]=arr[j++]; for(int k=start;k<=end;k++) arr[k]=temp[k-start]; } //==========測試程式碼================= public void test1() { int[] a = null; mergeSort(a); System.out.println(Arrays.toString(a)); } public void test2() { int[] a = {}; mergeSort(a); System.out.println(Arrays.toString(a)); } public void test3() { int[] a = { 1 }; mergeSort(a); System.out.println(Arrays.toString(a)); } public void test4() { int[] a = { 3, 3, 3, 3, 3 }; mergeSort(a); System.out.println(Arrays.toString(a)); } public void test5() { int[] a = { -3, 6, 3, 1, 3, 7, 5, 6, 2 }; mergeSort(a); System.out.println(Arrays.toString(a)); } public static void main(String[] args) { MergeSort2 demo =new MergeSort2(); demo.test1(); demo.test2(); demo.test3(); demo.test4(); demo.test5(); } }
MergeSort2
更多:資料結構與演算法合集