package class04; import java.util.Arrays; /** * 归并排序 */ public class Code01_MergeSort { //递归方式的归并排序 public static void mergeSort(int[] arr) { if (arr == null || arr.length < 2) { return; } process(arr, 0, arr.length - 1); } //把arr[L...R]排有序 //L...R N个数 //T(N) = 2 * T(N / 2) + O(N) //master公式 //a=2,b=2,d=1 //所以时间复杂度是:O(N*logN) private static void process(int[] arr, int L, int R) { if (L == R) { return; } int M = L + ((R - L) >> 1); process(arr, L, M);//使左边有序 process(arr, M + 1, R);//使右边有序 merge(arr, L, M, R);//合并左边和右边,使整体有序。 } //合并 private static void merge(int[] arr, int L, int M, int R) { int[] help = new int[R - L + 1]; int i = 0; int p1 = L;//左指针指向当前循环的,左侧数组的0位置。 int p2 = M + 1;//右指针指向当前循环的,右侧数组的0位置。 while (p1 <= M && p2 <= R) {//只要p1还没越界,并且p2还没越界 //如果左侧的这个数arr[p1] <= 右侧的这个数arr[p2], //那么将将辅助数组的i位置help[i],赋上arr[p1]这个值。p1++,i++。 //否则,p2++,i++。 help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++]; } //到这,要么p1越界,要么p2越界。 //p2越界 while (p1 <= M) { help[i++] = arr[p1++]; } //p1越界 while (p2 <= R) { help[i++] = arr[p2++]; } //help数组填好值之后,再填回arr数组。 for (i = 0; i < help.length; i++) { arr[L + i] = help[i]; } } //非递归方式的归并排序 public static void mergeSort2(int[] arr) { if (arr == null || arr.length < 2) { return; } int N = arr.length; int mergeSize = 1;//定义步长等于1 while (mergeSize < N) {//只要步长,小于数组的长度 int L = 0;//定义当前左组的0位置 while (L < N) { int M = L + mergeSize - 1;//当前左组的最右边的索引 = L + mergeSize - 1 if (M >= N) {//如果当前左组的最右边的索引,大于等于数组长度,就跳出内层的while循环。 break; } //当前右组的最右一个索引,等于,M + mergeSize)和(N - 1)中较小的那个。 int R = Math.min(M + mergeSize, N - 1); merge(arr, L, M, R);//合并左组和右组 L = R + 1;//新一轮的L来到,当前右组的加一的位置。 } if (mergeSize > N / 2) {//防止溢出 break; } mergeSize <<= 1;//步长*2 } } public static int[] generatorRandomArray(int maxSize, int maxValue) { int[] arr = new int[(int) (Math.random() * maxSize) + 2]; for (int i = 0; i < arr.length; i++) { arr[i] = (int) (Math.random() * maxValue); } return arr; } public static boolean isEquals(int[] arr1, int[] arr2) { if (arr1 == null && arr2 == null) { return true; } if (arr1 == null && arr2 != null) { return false; } if (arr1 != null && arr2 == null) { return false; } if (arr1.length != arr2.length) { return false; } for (int i = 0; i < arr1.length; i++) { if (arr1[i] != arr2[i]) { return false; } } return true; } public static int[] copyArray(int[] arr) { if (arr == null) { return null; } int[] res = new int[arr.length]; for (int i = 0; i < arr.length; i++) { res[i] = arr[i]; } return res; } public static void printArray(int[] arr) { if (arr == null) { return; } for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } public static void main(String[] args) { int maxSize = 100; int maxValue = 100; int testTimes = 100000; System.out.println("test start!"); for (int i = 0; i < testTimes; i++) { int[] arr1 = generatorRandomArray(maxSize, maxValue); int[] arr = copyArray(arr1); int[] arr2 = copyArray(arr1); int[] arr3 = copyArray(arr1); mergeSort(arr1); mergeSort2(arr3); Arrays.sort(arr2);//基准 if (!isEquals(arr1, arr2) || !isEquals(arr3, arr2)) { System.out.println("oops!"); printArray(arr); printArray(arr1); printArray(arr2); break; } } System.out.println("test end!"); } }
标签:归并,int,arr,mergeSize,process,排序 From: https://www.cnblogs.com/TheFloorIsNotTooHot/p/16861552.html