归并排序的实现
package algorithm;
public class MergeSort {
public static void main(String[] args) {
int[] arr = { 9, 8, 7, 0, 1, 3, 2, 5 };
// 插入排序 递归 + 分治
mergeSort(arr, 0, arr.length - 1);// 0 7
echoArr(arr, 0, arr.length - 1);
}
// 归并排序
// 时间复杂度 O(n log n)
public static void mergeSort(int[] arr, int left, int right) {
// 递归出口
if (left == right) {
return;
}
// 中间值
int middle = (left + right) / 2;
// 以中间值做区分 将问题细分化
mergeSort(arr, left, middle);
mergeSort(arr, middle + 1, right);
merge(arr, left, middle, right);
}
// 合并数据完成排序
public static void merge(int[] arr, int left, int middle, int right) {
// 用临时数组来保存每次排序后的数组
int[] sortArr = new int[arr.length];
// 左侧目前要操作的下标
int pointLeft = left;
// 右侧目前要操作的下标
int pointRight = middle + 1;
// 排序数组可存值的下标
int loc = left;
while (pointLeft <= middle && pointRight <= right) {
// 每次移动【临时数组】和【所移动的数组】下标都需自增
// 所以需要进行下标自增操作
if(arr[pointLeft] < arr[pointRight]) {
// 左边的比右边的值小
sortArr[loc ++] = arr[pointLeft ++];
} else {
// 左边的比右边的值大
sortArr[loc ++] = arr[pointRight ++];
}
}
// [2,3] [4,5] --结果数组--> [2,3]
// 挪动这样两个数据段, 会产生[2,3] 循环结束
// 其他情况举例如下
// [2,4] [3,5] --结果数组--> [2,3,4] ->右边剩余 5
// [2,5] [3,4] --结果数组--> [2,3,4] ->左边剩余 5
// 所以需要将剩余未移动数据依次放入排序数组中
// 左右两边都可能产生
while (pointLeft <= middle) {
sortArr[loc ++] = arr[pointLeft ++];
}
while (pointRight <= right) {
sortArr[loc ++] = arr[pointRight ++];
}
// 至此 排序已经完成
// 排序数据在临时数组中 需挪动至原数组中
for (int i = left; i <= right; i++) {
arr[i] = sortArr[i];
}
}
// 输出数组内容的方法
public static void echoArr(int[] arr,int left,int right) {
for (int i = left; i <= right; i++) {
System.out.print(arr[i]);
}
System.out.println();
}
}
附执行结果如下:
01235789