一、基本介绍
归并排序(MERGE- SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治( divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案”修补”在一起,即分而治之)。
说明:
可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。分阶段可以理解为就是递归拆分子序列的过程。
代码实现:
import java.util.Arrays;
//归并排序
public class MergeSort {
public static void main(String[] args) {
int[] array = {8,4,5,7,1,3,6,2};
int[] temp = new int[array.length];
getMergeSort(array,0,array.length-1,temp);
System.out.println("归并排序后:"+Arrays.toString(array));
}
//分+合的方法
public static void getMergeSort(int[] array,int left,int right,int[] temp){
if(left < right){
int middle = (left + right) / 2; //中间索引
//向左递归分解
getMergeSort(array,left,middle,temp);
//向右递归分解
getMergeSort(array,middle+1,right,temp);
//到合并
merge(array,left,middle,right,temp);
}
}
//合并方法
/*
* int[] array :要排序的原始数组
* left: 左边有序序列的初始索引
* middle: 中间索引
* right: 右边索引
* int[] temp: 用来做中转的数组
* */
public static void merge(int[] array,int left, int middle,int right,int[] temp) {
int i = left; //左边有序序列的初始索引
int j = middle+1; //右边有序序列的初始索引
int t = 0; //指向中转数组temp当前索引
//1.先把左右两边的数据按照规则填充到temp,
//直到左右两边的有序序列有一边处理完毕为此
while(i <= middle && j <= right){ //继续
//如果左边有序序列的指向元素小于等于右边有序序列的指向元素,就将元素给中转数组temp
if(array[i] <= array[j]){
temp[t] = array[i];
t++;
i++;
}else { //如果左边有序序列的指向元素大于右边有序序列的指向元素,就将右边元素给中转数组temp
temp[t] = array[j];
t++;
j++;
}
}
//2.把有剩余数据的一边的数据一次全部填充到temp
while (i <= middle){ //左边的有序序列还有剩余元素,就全部填充到temp
temp[t] = array[i];
t++;
i++;
}
while (j <= right){ //右边的有序序列还有剩余元素,就全部填充到temp
temp[t] = array[j];
t++;
j++;
}
//3.将temp数组的元素拷贝到array
//注意:并不是每次拷贝所有
t = 0;
int tempLeft = left;
while(tempLeft <= right){
array[tempLeft] = temp[t];
t++;
tempLeft++;
}
}
}
结果展示:
速度测试:
public static void main(String[] args) {
int[] array = new int[8000000];
for(int i = 0; i < 8000000; i++){
array[i] =(int) (Math.random() * 8000000); //生成一个[0,10000)数
}
int[] temp = new int[array.length];
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS");
String data1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间:"+data1Str);
getMergeSort(array,0, array.length-1,temp);
Date date2 = new Date();
String data2Str = simpleDateFormat.format(date2);
System.out.println("排序后的时间:"+data2Str);
}
结果:8000000万个数据只需不到2秒