import java.util.Arrays;
/**
* @author mccrea
* @version 1.0
* @description: 归并排序
* @date 2020/9/20 14:09
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = new int[] {1,4,2,7,8,2,4,8,9,0};
mergeSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
/**
* @description: 归并排序
* @param:
* @param arr 待排序数组
* @param left 待排序的左下标
* @param right 待排序的右下标
* @return: void
* @author mccrea
* @date: 2020/9/20 14:40
*/
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
// 取中点,同时防止数字超过Integer.MAX_VALUE,算术运算符优先级高于位运算,所有后面需要加括号
int mid = left + ((right - left) >> 1);
// 拆分成两个小的有序集合继续递归
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// 把两个小的有序集合归并成一个大的有序集合
merge(arr, left, mid, right);
}
}
/**
* @description: 归并排序合并方法
* @param:
* @param arr 待排序数组
* @param left 需要归并部分的左下标
* @param mid 第一部分数组尾部下标
* @param right 需要归并部分右下标
* @return: void
* @author mccrea
* @date: 2020/9/20 14:10
*/
private static void merge(int[] arr, int left, int mid, int right) {
// 临时数组存储排序后数组
int[] tempArr = new int[right - left + 1];
// 左部分数组指针
int tempLeft = left;
// 右部分数组指针
int tempRight = mid + 1;
// 临时数组指针
int temp = 0;
// 前后俩数组向后遍历,较小的数存入临时数组
while (tempLeft <= mid && tempRight <= right) {
if (arr[tempLeft] < arr[tempRight]) {
tempArr[temp ++] = arr[tempLeft ++];
} else {
tempArr[temp ++] = arr[tempRight ++];
}
}
// 左边数组还未遍历完
while (tempLeft <= mid) {
tempArr[temp ++] = arr[tempLeft ++];
}
// 右边数组还未遍历完
while (tempRight <= right) {
tempArr[temp ++] = arr[tempRight ++];
}
// 排序后的数组存入原数组
for (int i = 0; i < tempArr.length; i ++) {
arr[left + i] = tempArr[i];
}
}
}