You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
9.0 KiB
344 lines
9.0 KiB
package leo.class03_04;
|
|
|
|
|
|
import leo.util.ArrayUtil;
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
|
/**
|
|
* @author Leo
|
|
* @ClassName MergeSort
|
|
* @DATE 2020/11/21 9:21 下午
|
|
* @Description 归并排序
|
|
*/
|
|
public class MergeSort {
|
|
|
|
|
|
/**
|
|
* @author Leo
|
|
* @ClassName MergeSort
|
|
* @DATE 2020/11/21 9:21 下午
|
|
* @Description 递归版归并排序
|
|
*/
|
|
public static class Recursion {
|
|
|
|
/**
|
|
* 功能描述 : 递归版归并排序
|
|
*
|
|
* @param arr
|
|
* @return void
|
|
* @author Leo
|
|
* @date 2020/11/21 9:23 下午
|
|
*/
|
|
public static void mergeSort(int[] arr) {
|
|
if (arr == null || arr.length < 2) {
|
|
return;
|
|
}
|
|
process(arr, 0, arr.length - 1);
|
|
}
|
|
|
|
private static void process(int[] arr, int L, int R) {
|
|
if (L == R) {
|
|
return;
|
|
}
|
|
int mid = L + ((R - L) >> 1);
|
|
process(arr, L, mid);
|
|
process(arr, mid + 1, R);
|
|
merge(arr, L, mid, R);
|
|
}
|
|
|
|
/**
|
|
* 功能描述 : 合并
|
|
*
|
|
* @param arr 数组
|
|
* @param L 左面第一个下标
|
|
* @param M 中间下标
|
|
* @param R 右面最后一个下标
|
|
* @return void
|
|
* @author Leo
|
|
* @date 2020/11/21 9:28 下午
|
|
*/
|
|
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;
|
|
int p2 = M + 1;
|
|
while (p1 <= M && p2 <= R) {
|
|
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
|
|
}
|
|
while (p1 <= M) {
|
|
help[i++] = arr[p1++];
|
|
}
|
|
while (p2 <= R) {
|
|
help[i++] = arr[p2++];
|
|
}
|
|
|
|
for (i = 0; i < help.length; i++) {
|
|
arr[L + i] = help[i];
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static class Recursion1 {
|
|
public static void mergeSort(int[] arr) {
|
|
if (arr.length < 2 || arr == null) {
|
|
return;
|
|
}
|
|
process(arr, 0, arr.length - 1);
|
|
|
|
}
|
|
|
|
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 p1 = L;
|
|
int p2 = M + 1;
|
|
int i = 0;
|
|
int[] help = new int[R - L + 1];
|
|
while (p1 <= M && p2 <= R) {
|
|
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
|
|
}
|
|
while (p1 <= M) {
|
|
help[i++] = arr[p1++];
|
|
}
|
|
while (p2 <= R) {
|
|
help[i++] = arr[p2++];
|
|
}
|
|
for (i = 0; i < help.length; i++) {
|
|
arr[L + i] = help[i];
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
public static class Recursion2 {
|
|
public static void mergeSort(int[] arr) {
|
|
if (arr.length < 2 || arr == null) {
|
|
return;
|
|
}
|
|
process(arr, 0, arr.length - 1);
|
|
}
|
|
|
|
private static void process(int[] arr, int l, int r) {
|
|
if (l == r) {
|
|
return;
|
|
}
|
|
int mid = l + ((r - l) >> 1);
|
|
process(arr, l, mid);
|
|
process(arr, mid + 1, r);
|
|
merge(arr, l, mid, r);
|
|
}
|
|
|
|
private static void merge(int[] arr, int l, int mid, int r) {
|
|
if (l == r) {
|
|
return;
|
|
}
|
|
int p1 = l;
|
|
int p2 = mid + 1;
|
|
int[] help = new int[r - l + 1];
|
|
int i = 0;
|
|
while (p1 <= mid && p2 <= r) {
|
|
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
|
|
}
|
|
while (p1 <= mid) {
|
|
help[i++] = arr[p1++];
|
|
}
|
|
while (p2 <= r) {
|
|
help[i++] = arr[p2++];
|
|
}
|
|
for (i = 0; i < help.length; i++) {
|
|
arr[l + i] = help[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class Recursion3 {
|
|
public static void mergeSort(int[] arr) {
|
|
if (arr.length < 2 || arr == null) {
|
|
return;
|
|
}
|
|
process(arr, 0, arr.length - 1);
|
|
}
|
|
|
|
public 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 p1 = l;
|
|
int p2 = m + 1;
|
|
int[] help = new int[r - l + 1];
|
|
int i = 0;
|
|
while (p1 <= m && p2 <= r) {
|
|
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
|
|
}
|
|
while (p1 <= m) {
|
|
help[i++] = arr[p1++];
|
|
}
|
|
while(p2<=r){
|
|
help[i++] = arr[p2++];
|
|
}
|
|
for (i = 0; i < help.length; i++) {
|
|
arr[l + i] = help[i];
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @author Leo
|
|
* @ClassName MergeSort
|
|
* @DATE 2020/11/21 9:21 下午
|
|
* @Description 非递归版归并排序
|
|
*/
|
|
public static class NonRecursive{
|
|
|
|
public static void mergeSort(int[] arr) {
|
|
if (arr.length < 2 || arr == null) {
|
|
return;
|
|
}
|
|
int N = arr.length;
|
|
int mergeSize = 1;
|
|
while (mergeSize < N) {
|
|
int L = 0;
|
|
while (L < N) {
|
|
int M = mergeSize + L - 1;
|
|
if (M >= N) {
|
|
break;
|
|
}
|
|
int R = Math.min(M + mergeSize, N - 1);
|
|
merge(arr, L, M, R);
|
|
L = R + 1;
|
|
}
|
|
if (mergeSize > N / 2) {
|
|
break;
|
|
}
|
|
mergeSize <<= 1;
|
|
|
|
}
|
|
|
|
}
|
|
private static void merge(int[] arr, int L, int M, int R) {
|
|
if (L == R) {
|
|
return;
|
|
}
|
|
int[] help = new int[R - L + 1];
|
|
int p1 = L;
|
|
int p2 = M + 1;
|
|
int i = 0;
|
|
while (p1 <= M && p2 <= R) {
|
|
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
|
|
}
|
|
while (p1 <= M) {
|
|
help[i++] = arr[p1++];
|
|
}
|
|
while (p2 <= R) {
|
|
help[i++] = arr[p2++];
|
|
}
|
|
for (i = 0; i < help.length; i++) {
|
|
arr[L + i] = help[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class NonRecursive1 {
|
|
|
|
public static void mergeSort(int[] arr) {
|
|
if (arr.length < 2 || arr == null) {
|
|
return;
|
|
}
|
|
int arrLength = arr.length;
|
|
int mergeSize = 1;
|
|
|
|
while (mergeSize < arrLength) {
|
|
int L = 0;
|
|
while (L < arrLength) {
|
|
int M = L + mergeSize - 1;
|
|
if (M >= arrLength) {
|
|
break;
|
|
}
|
|
int R = Math.min(M + mergeSize, arrLength - 1);
|
|
merge(arr, L, M, R);
|
|
L = R + 1;
|
|
}
|
|
//防越界
|
|
if (mergeSize > arrLength / 2) {
|
|
break;
|
|
}
|
|
mergeSize <<= 1;
|
|
}
|
|
|
|
}
|
|
|
|
private static void merge(int[] arr, int l, int m, int r) {
|
|
if (l == r) {
|
|
return;
|
|
}
|
|
int pl = l;
|
|
int pr = m + 1;
|
|
int[] help = new int[r - l + 1];
|
|
int i = 0;
|
|
while (pl <= m && pr <= r) {
|
|
help[i++] = arr[pl] <= arr[pr] ? arr[pl++] : arr[pr++];
|
|
}
|
|
while (pl <= m) {
|
|
help[i++] = arr[pl++];
|
|
}
|
|
while (pr <= r) {
|
|
help[i++] = arr[pr++];
|
|
}
|
|
for (i = 0; i < help.length; i++) {
|
|
arr[l + i] = help[i];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public static void main(String[] args){
|
|
int maxSize = 50;
|
|
int range = 80;
|
|
int testOfTime = 10000;
|
|
boolean succeed = true;
|
|
for (int i = 0; i < testOfTime; i++) {
|
|
int[] arr = ArrayUtil.randomArray(maxSize, range);
|
|
int[] anotherArr = ArrayUtil.copyArray(arr);
|
|
Recursion3.mergeSort(arr);
|
|
Arrays.sort(anotherArr);
|
|
if (!ArrayUtil.isEqual(arr, anotherArr)) {
|
|
succeed = false;
|
|
ArrayUtil.printArr(arr, "arr");
|
|
ArrayUtil.printArr(anotherArr, "anotherArr");
|
|
break;
|
|
}
|
|
}
|
|
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|