1、问题
对n个不同的数构成的数组A[1…n]进行排序,其中n=2^k
思路:
归并排序是多次将相邻两个或两个以上的有序表合并成一个新的有序表。
最简单的归并是将两个有序的子表合并成一个有序的表,即二分归并排序。
2、解析
设待排序表有10个记录,其关键字分别为{18,2,20,34,12,32,6,16,1,5}。
采用二分归并排序方法排序过程:
3、设计
void MergeSort(RecType R[],int n) {
int length;
for(length=1;length<n;length=length*2){
MergePass(R,length,n);
}
}
void Merge(RecType R[],int low,int mid,int high){
RecType *R1;
int i=low,j=mid+1,k=0;
R1=(RecType *)malloc((high-low+1)*sizeof(RecType));
while(i<=mid&&j<=high){
if(R[i].key<=R[j].key){
R1[k]=R[i];
i++;
k++;
}
else{
R1[k]=R[j];
j++;
k++;
}
}
while(i<=mid){
R1[k]=R[i];
i++;
k++;
}
while(j<=high){
R1[k]=R[j];
j++;
k++;
}
for(k=0,i=low;i<=high;i++,k++){
R[i]=R1[k];
}
}
void MergePass(RecType R[],int length,int n){ //一趟二路归并
int i;
for(i=0;i+2*length-1<n;i=i+2*length){ //归并length长的两相邻子表
Merge(R,i,i+length-1,i+2*length-1);
}
if(i+length-1<n){ //余下两个子表,后者长度小于length
Merge(R,i,i+length-1,n-1);//归并两个子表
}
}
4、分析
每一趟归并的时间复杂度为O(n)。
总共需进行[log2 n]趟。
二分归并排序的时间复杂度为O(nlog2 n)。