1、介绍
该算法采用分治策略,将问题分成一些小的问题后递归求解,然后再将每个分支的结果进行整合。使用空间换时间的方式完成
2、实现思路
将一个待排序序列从中间进行递归分割,然后将每一端的数据在进行分割,拆分到一定程度后再将左右两端的元素按照大小依次放入临时数组当中,最后将临时数组中的数据拷贝到原数组中
3、代码实现
package com.lyw.review510;
import java.util.Arrays;
// 归并排序
public class MergeSort {
public static void main(String[] args) {
int[] arr = {4, 1, 6, 8, 9, 0};
int[] temp = new int[arr.length];
mergeSort(arr, 0, arr.length - 1, temp);
System.out.println(Arrays.toString(arr));
}
// 分加合的方法
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
// 中间变量
int mid = (left + right) / 2;
// 中间变量的左边序列进行再拆分
mergeSort(arr, left, mid, temp);
// 然后拆分中间变量的右边的序列
mergeSort(arr, mid + 1, right, temp);
// 拆分完左边的和右边的数据之后然后合并当前元素
merge(arr, left, mid, right, temp);
}
}
// 合并两个序列的数据 -> 临时数组temp上
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left; // 记录左边序列的开始索引
int j = mid + 1; // 右边序列的开始索引
int t = 0; // 记录临时数组元素的下标
// 1、将左边的序列和右边的序列依次比较插入临时数组中,直到左右两边有序列表,有一个先处理完毕为止
// 满足这个条件说明左右两端的序列没有一端的数据填充完
while (i <= mid && j <= right) {
// 记得别忘记移动索引
// 如果左边的元素小于右边的元素,就将左边的元素先添加到临时数组中
if (arr[i] < arr[j]) {
temp[t] = arr[i];
t++;
i++;
} else { // 反之说明右边的数据小于等于左边的数据
temp[t] = arr[j];
j++;
t++;
}
}
// 2、将两端数组中其中一个剩余的数组按照顺序添加到临时表中
// 将左边的序列剩余的数组依次拷贝到临时数组中
while(i <= mid) {
temp[t] = arr[i];
t++;
i++;
}
// 将有边的序列剩余的数组依次拷贝到临时数组中
while(j <= right) {
temp[t] = arr[j];
t++;
j++;
}
// 3、最后将数组中的数据拷贝到原数组中
t = 0; // 初始化临时数组中的下标元素,方便拷贝
int tempLeft = left; // 用作记录原数组中的下标
while(tempLeft <= right) {
arr[tempLeft] = temp[t];
t++;
tempLeft++;
}
}
}
仅供参考