归并排序 是利用递归和分而治之的技术 将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成越来越大的有序序列。
public static int []sort(int [] a,int low,int high)
{
int mid=(low+high)/2;
if(low<high){
sort(a,low,mid);//递归对左边元素进行排序
sort(a,mid+1,high);//递归对右边元素进行排序
merge(a,low,mid,high);//左右归并
}
return a;
}
public static void merge(int [] a,int low,int mid,int high)
{
int []temp=new int[high-low+1];//新建一个和原来大小一样数组
int i=low;
int j=mid+1;
int k=0;
while(i<=mid&&j<=high){//把较小的数先移到新数组中
if(a[i]<a[j]){
temp[k++]=a[i++];
}else{
temp[k++]=a[j++];
}
}
while(i<=mid){//把左边剩余的数移入数组
temp[k++]=a[i++];
}
while(j<=high){//把右边剩余的数移入数组
temp[k++]=a[j++];
}
//把新数组中的数覆盖nums数组
for(int x=0;x<temp.length;x++){
a[x+low]=temp[x];
}
}
算法分析
(1)稳定性
归并排序是一种稳定的排序。
(2)存储结构要求
可用顺序存储结构。也易于在链表上实现。
(3)时间复杂度
对长度为n的文件,需进行趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。
(4)空间复杂度
需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。