1.问题
二分归并排序:对n个不同的数构成的数组A[1…n]进行排序,其中n=2^k
2.解析
选择中间的数,把数组对半划分。分别对 子问题1 和 子问题2 进行排序,最后把这两个排好序的问题 综合到一个问题。
因此,二分归并排序也涉及到三个问题:
1) 把大问题归约成 规模较小的子问题 。
2) 把子问题独立求解的过程。
3) 把所有子问题 综合解的过程。
3.设计
void mergearray(int a[],int first,int mid,int last,int temp[]) //将两个有序数组合并排序
{
int i=first,j=mid+1;
int m=mid,n=last;
int k=0;
while(i<=m&&j<=n)
{
if(a[i]<a[j])
temp[k++]=a[i++];
else
temp[k++]=a[j++];
}
while(i<=m)
temp[k++]=a[i++];
while(j<=n)
temp[k++]=a[j++];
for(i=0;i<k;i++)
a[first+i]=temp[i];
}
void mergesort(int a[],int first,int last,int temp[]) //将两个任意数组合并排序
{
if(first<last)
{
int mid=(first+last)/2;
mergesort(a,first,mid,temp); //左边有序
mergesort(a,mid+1,last,temp); //右边有序
mergearray(a,first,mid,last,temp); //再将两个有序数组合并
}
}
4.分析
最坏比较次数:n-1
最好比较次数:n/2
所以算法复杂度:W(n)=2W(n/2)+n-1,n=2^k;如果n=1,则W(1)=0
W(n)=2W(n/2)+n-1 = nlogn -n + 1;
2W(n/2)是:把规模为n的问题分成规模为n/2的子问题。这是两个子问题的工作量。
n-1: 两个排好序的子数组合并成整体的工作量。
W(1)=0,是说 规模为1 的工作量是0.
所以 时间复杂度为O(nlogn)