归并算法的思想,主要是通过分治的思想,把大的问题分成一个个小的问题,把问题简单化
分:把数组拆分成单个元素
治:把数组按顺序合并起来,然后依次比较两边元素的大小,把小的放入一个新的数组中去,直到一边的数据完全被放入,
最后把剩下的所有的数据按顺序放入集合去
package datastructure.sort;
/*
@CreateTime 2021/9/15 10:15
@CreateBy cfk
*/
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class MergeSort {
public static void main(String[] args) {
int[] arr = {8,4,5,7,1,3,6,2};
int[] tmp = new int[arr.length];
mergeSort(arr,0, arr.length-1,tmp);
System.out.println(Arrays.toString(arr));
// 测试80000条数据 冒泡排序所需要的时间 1s
// int[] arr = new int[80000];
// int[] tmp = new int[arr.length];
// for (int i = 0; i < 80000; i++) {
// arr[i] = (int) (Math.random()*8000000);
// }
//
// SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
// String s1 = sdf.format(new Date());
// System.out.println(s1);
//
//
// mergeSort(arr,0,arr.length-1,tmp);
//
//
// String s2 = sdf.format(new Date());
// System.out.println(s2);
}
//分治
public static void mergeSort(int[] arr, int left, int right, int[] tmp){
//分 不断递归直到分成一个个单一的元素
if (left < right) {
int mid = (left + right)/2;
mergeSort(arr,left,mid,tmp);
mergeSort(arr,mid+1,right,tmp);
//合并
merge(arr,left,right,tmp);
}
}
//合并
public static void merge(int[] arr, int left, int right, int[] tmp) {
//可以不初始化临时数组
//到需要使用到时才生成对应大小的临时数组
// int[] tmp = new int[right - left + 1];
int l = left; //初始化左指针
int mid = (left + right)/2;
int r = (left + right)/2 + 1; //初始化右指针
int t = 0; //初始化tmp数组索引
//当元素左指针以及右指针没有移动到最后时
while (l <= mid && r <= right) {
//当左边元素比右边元素小,就把左边的元素保存在新的数组中,并且让左指针以及索引向后移动
if (arr[l] <= arr[r]){
tmp[t] = arr[l];
l++;
t++;
//当右边元素比左边元素小,就把右边的元素保存在新的数组中,并且让右指针以及索引向后移动
}else {
tmp[t] = arr[r];
r++;
t++;
}
}
//当右指针已经移动完毕后,把剩下的所有左边元素添加到新的数组中
while (l <= mid) {
tmp[t] = arr[l];
l++;
t++;
}
//当左指针已经移动完毕后,把剩下的所有右边元素添加到新的数组中
while (r <= right) {
tmp[t] = arr[r];
r++;
t++;
}
//把新数组存储的所有元素存储到arr中去 这里并不是一次性把所有的元素都转过去
//因为我们这里采用的是事先就已经写好一个临时数组 它是固定长度的 如果只传两位数 后面的也有默认值
//所以在判断的时候会出现数组越界
//所以我们这里是分开每次存储 例如 第一次存 0 1 第二次存 2 3 再存 0 3
t = 0;
int tmpLeft = left;
while (tmpLeft <= right) {
arr[tmpLeft] = tmp[t];
t++;
tmpLeft++;
}
}
}