归并排序
自上而下的归并
归并排序主要思想:(借助于一个辅助数组aux)
1.把所有的数据拷贝到辅助数组备份
2.对辅助数组使用两个指针,分别从左右逐个对比,原数组也使用一个指针
3.比较结果小的值把原数组的值替换,原数组指针加一
public class MergeSort01 {
public static Comparable[] aux;
public static void merge(Comparable[] a,int lo,int mid,int hi) {
//保存数组副本
//1.把所有的数据拷贝到辅助数组备份
for(int k=lo;k<=hi;k++) {
aux[k]=a[k];
}
//对辅助数组使用两个指针
int i=lo;
int j=mid+1;
//mid是左右指针扫描的分界
//分别从左右逐个对比
for(int k=lo;k<=hi;k++) {
//此处是原数组指针k,每次结束循环自动加一
if(i>mid) {a[k]=aux[j++];}
//左边指针全部扫描结束,把右边所有数值依次赋给原数组
else if(j>hi) {a[k]=aux[i++];}
//右边指针全部扫描结束,把左边所有数值依次赋给原数组
else if(AllSort.less(aux[i],aux[j])) {a[k]=aux[i++];}
else {a[k]=aux[j++];}
//此处是比较左右指针对应的值,比较结果小的值把原数组的值替换
}
}
public static void sort(Comparable[] a) {
aux=new Comparable[a.length];
mergeSort(a,0,a.length-1);
}
//归并排序因为要求mid两边已经是排序好的结果,所以此处使用迭代,
//当迭代到只有两个比较项时再次迭代则结束,依次往回结束迭代,最终完全排序
public static void mergeSort(Comparable[] a,int lo,int hi) {
int mid=lo+(hi-lo)/2;
if(hi<=lo)return;
mergeSort(a,lo,mid);
mergeSort(a,mid+1,hi);
merge(a,lo,mid,hi);
}
自下而上的归并
与自上而下不同,此处使用for循环,merge方法同上,
public static void mergeSort01(Comparable[] a) {
int N=a.length;
for(int size=1;size<a.length;size+=size) {
for(int i=0;i<N-size;i+=2*size) {
//防止数组越界此处使用 Math.min(i+size+size-1, N-1)
merge(a,i,i+size-1,Math.min(i+size+size-1, N-1));
}
}
}