归并算法
分而治之
归并排序介绍:
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
![alt text](image-7.png)
说明:
可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。分阶段可以理解为就是递归拆分子序列的过程。
递归的想法进行一个实现
优化版
package Java.DataStructuresAndAlgorithms.Algorithms.sort;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MergeSort {
public static void main(String[] args) {
int[] arr = new int[8000000];
for (int i = 0; i < 8000000; i++) {
arr[i] = (int) (Math.random() * 8000000);
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间是=" + date1Str);
int temp[] = new int[arr.length];
mergeSort(arr, 0, arr.length - 1, temp);
Date date2 = new Date();
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd
// HH:mm:ss");
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序后的时间是=" + date2Str);
}
// 分+合的方法
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);
}
}
// 合并的方法
/**
*
* @param arr 排序的原始的数组
* @param left 索引
* @param mid
* @param right
* @param temp 中转的数组
*/
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left; // 初始化i,左边有序序列的初始索引
int j = mid + 1; // 初始化j,右边的索引
int t = 0; // 指向temp数组的当前索引
while (i <= mid && j <= right) {
// 如果左边的有序序列的当前的元素,是小于等于这个右边的
// 那么我们将左边的元素填充到temp的数组之中
// 然后t++,i++
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t += 1;
i += 1;
} else {
temp[t] = arr[j];
t += 1;
j += 1;
}
}
// 把有剩余数据的一边全部都放到这个temp这个数组当中去
while (i <= mid) { // 左边的元素有序序列还有剩余的元素,全部进行一个填充
temp[t] = arr[i];
t += 1;
i += 1;
}
while (j <= right) {
temp[t] = arr[j];
t += 1;
j += 1;
}
// 将temp这个数组中的元素copy到这个arr中
// 注意这个并不是每次都是全部的拷贝所有
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft] = temp[t];
t += 1;
tempLeft += 1;
}
}
}