一、基本思路
首先,我们要了解一下归并这个名字的由来,其中,"归" 为递归,"并"为合并,意思是先递归后合并,递归其实是用了分治法这种思想,它将待排序数组分为两组,每一组又再分为两组,依次类推,直到最后一次只有一个,不再递归,将相邻的两组合并为比较大的一组,这个大的一组又与相邻的已经合并的同样大的那组再合并,直到最后合并成原来数组一样的大小,排序也就完成了,关于合并的过程看下面例子就可以啦
二、例子
这里引用一位博主的图,清晰明了 博客地址:http://www.cnblogs.com/chengxiao/
先分后治,在下半部分,也就是合并部分,我们采用的合并方法如下
1.定义一个临时数组temp用于保存合并结果
2.以4 5 7 8 、1 2 3 6 的合并为例
3.都从第一个元素开始,1<4 , 1 移进 temp , 2<4 ,如上,........ 6>4 ,4移进temp ,当有一遍的数都移到临时数组后,把另外一组的数依次移进去,然后再把临时数组赋给原数组就可以了
三、代码实现
public class MergeSort {
public static void main(String[] args) {
MergeSort mergeSort=new MergeSort();
int [] a=new int[]{3,5,7,9,8,6,2,1,4,0};
int [] temp=new int[a.length];
mergeSort.mergeSort(a,0,a.length-1,temp);
for(int item:a){
System.out.print(item+" ");
}
}
private void mergeSort(int[] a,int left,int right,int[] temp){
if(left<right){ //递归终止条件
int mid=(left+right)/2;
mergeSort(a, left, mid, temp);
mergeSort(a, mid+1, right, temp);
merge(a,left,mid,right,temp);
}
}
private void merge(int[] a, int left, int mid, int right, int[] temp) {
int i=left;
int j=mid+1;
int t=0;
while(i<=mid&&j<=right){
if(a[i]<=a[j]){
temp[t++]=a[i++];
}
else{
temp[t++]=a[j++];
}
}
while(i<=mid){
temp[t++]=a[i++];
}
while(j<=right){
temp[t++]=a[j++];
}
t=0;
while(left<=right){ //把临时数组复制回原数组
a[left++]=temp[t++];
}
}
}
四、复杂度
分治法使得复杂度为O(nlogn),合并算法为O(n),其最佳,最差,平均时间复杂度均为O(nlogn)