// TODO 归并排序
public class MergeSort {
public static void main(String[] args) {
// int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
// 测试时间复杂度 O(n log n)
int [] arr = new int[80000];
int[] temp = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
// 生成 [0,8000000)的随机数
arr[i] = (int) (Math.random()*8000000);
}
long start_Time = System.currentTimeMillis();
mergeSort(arr,temp,0,arr.length-1);
long stop_Time = System.currentTimeMillis();
System.out.printf("耗费 %d ms",stop_Time - start_Time);
// System.out.println(Arrays.toString(arr));
}
// 分 + 合 方法
public static void mergeSort(int[]arr ,int[] temp,int left,int right){
if(left<right){
int center = (left + right) /2; // 中间索引
// 向左递归 进行分解
mergeSort(arr,temp,left,center);
// 向右递归进行分解
mergeSort(arr,temp,center +1,right);
// 合并
merge(arr,temp,left,center,right);
}
}
/**
* 合并方法
*
* @param arr 排序的原始数组
* @param temp 合并存储中间结果的数组
* @param left 最左边的索引
* @param center 中间的索引
* @param right 最右边的索引
*/
private static void merge(int[] arr, int[] temp, int left, int center, int right) {
int leftIndex = left; // 初始化 l ,左边的有序序列初始索引
int c = center + 1; // 初始化 c,右边开始的索引
int index = 0; // temp 数组的初始索引
/*
第一步 先把 左右两步(有序)的数据按照规则填充到temp数组
直到左右两边的有序序列,有一边处理完毕为止
*/
while (leftIndex <= center && c <= right) {
if (arr[leftIndex] <= arr[c]) {
temp[index] = arr[leftIndex];
leftIndex++;
} else {
temp[index] = arr[c];
c++;
}
index++;
}
//(2) 把有剩余的一边数据依次全部填充到temp
while (leftIndex <= center){
temp[index] = arr[leftIndex];
leftIndex ++;
index ++;
}
while (c <= right){
temp[index] = arr[c] ;
index ++;
c ++;
}
//(3) 把临时数组的拷贝到arr中
// 注意 ,并不是 每次都拷贝所有
index = 0;
int tempLeft = left;
while(tempLeft <= right){
arr[tempLeft] = temp[index];
index ++;
tempLeft ++;
}
}
}
十大排序之归并排序
猜你喜欢
转载自blog.csdn.net/qq_43205282/article/details/105399652
今日推荐
周排行