基本思想
将一个大的数组递归地分成两半分别排序,然后将结果归并(将两个有序的数组归并成一个更大的数组)
方法。
具体看封装类代码中的注释。
归并排序封装类完整实现
public class MergeSort {
/**
* 归并所需的辅助数组
*/
private static Comparable[] temp;
/**
* 自顶向下的归并排序
*
* 此方法中分配辅助数组的空间并调用下面的sort()方法。这个方法只是封装类的接口方法,
* 真正的排序是在sort()方法中实现的,因为自顶向下归并时需要辅助数组,开辟辅助数组是
* 万万不能写在递归方法里的,所以采用这种方式写,当然也可以在数组声明时就分配空间,这
* 只是写法问题,重点还是要注意不能在递归方法中开辟辅助数组。
*
* @param a 待排数组
*/
public static void sortFromTop(Comparable[] a){
//一次性分配空间
temp=new Comparable[a.length];
sort(a,0,a.length-1);
}
/**
* 自底向上的归并排序
*
* @param a 待排数组
*/
public static void sortFromBottom(Comparable[] a){
int N=a.length;
temp=new Comparable[N];
for(int sz=1;sz<N;sz=sz+sz)
for(int lo=0;lo<N-sz;lo+=sz+sz)
merge(a,lo,lo+sz-1,Math.min(lo+sz+sz-1, N-1));
}
/**
* 自顶向下的归并排序,对数组进行排序的递归方法
*/
private static void sort(Comparable[] a,int lo,int hi){
if(hi<=lo)return;
int mid=lo+(hi-lo)/2;
sort(a,lo,mid); //将左半边排序
sort(a,mid+1,hi); //将右半边排序
merge(a,lo,mid,hi); //归并
}
/**
* 将a[lo..mid]和a[mid+1..hi]进行原地归并
*/
private static void merge(Comparable[] a,int lo,int mid,int hi){
temp=new Comparable[a.length];
int i=lo,j=mid+1;
for(int k=lo;k<=hi;k++)
temp[k]=a[k];
for(int k=lo;k<=hi;k++){
if(i>mid)a[k]=temp[j++];
else if(j>hi)a[k]=temp[i++];
else if(less(temp[j],temp[i]))a[k]=temp[j++];
else a[k]=temp[i++];
}
}
/**
* 比较大小
*/
private static boolean less(Comparable v,Comparable w){
return v.compareTo(w)<0;
}
}