完整代码如下
/**
* @description: 归并排序:80000个数据13ms
* @author: Tian
* @time: 2020/8/15 10:14
*/
public class MregeSort {
public static void main(String[] args) {
// int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
int[] arr = new int[80000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 8000000);
}
long currentTimeMillis = System.currentTimeMillis();
int[] temp = new int[arr.length];
mergeSort(arr, 0, arr.length - 1,temp);
long currentTimeMillis1 = System.currentTimeMillis();
System.out.println("共花费了" + (currentTimeMillis1 - currentTimeMillis) + "ms");
}
//拆分的方法
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);
}
}
//合并的方法
public static void merge(int[] arr, int left, int mid,int right, int[] temp) {
//最后一次的合并
int l = left;
// int mid = (left + right) / 2;
int r = mid + 1;
int t = 0;
//一,按照规则,将这些放在右边的temp[]中,直到一方放完
while (l < mid + 1 && r <= right) {
if (arr[l] < arr[r]) {
temp[t] = arr[l];
t++;
l++;
} else {
temp[t] = arr[r];
t++;
r++;
}
}
//二.jiang没有排的元素放在tem[]数组的后边
//zhehsi 左边放满了
while (r <= right) {
temp[t] = arr[r];
t++;
r++;
}
//zhehsi 右边放满了
while (l < mid + 1) {
temp[t] = arr[l];
t++;
l++;
}
//三.将temp[]数组中的元素copy进原来的数组
t = 0;
int templeft = left;
/* for (;templeft < arr.length;templeft++,t++){
arr[templeft] = arr[t];
}*/
//以上代码是错误的,因为并不是每一次合并都会拷贝所有
while (templeft <= right) {
arr[templeft] = temp[t];
t++;
templeft++;
}
//System.out.println(Arrays.toString(arr));
}
}
注意事项:
- 递归拆分之后的合并有很多细节不要出错,eg:合并的第一步,按照规则存放元素到临时数组中,如果用以下代码数据多的时候程序就不会结束.arr[l] =arr[r] 出现死循环.
while (l < mid + 1 && r <= right) {
if (arr[l] < arr[r]){
temp[t] = arr[l];
t++;
l++;
}
if (arr[l] > arr[r]){
temp[t] = arr[r];
t++;
r++;
}
}
- 将temp[]数组中的元素copy进原来的数组,并不会每次都拷贝所有