1.问题
二分归并排序:对n个不同的数构成的数组A[1…n]进行排序,其中n=2^k
2.解析
归并排序算法有两个基本的操作,一个是分,也就是把原数组划分成两个子数组的过程。另一个是并,它将两个有序数组合并成一个更大的有序数组。
3.设计
//归并
int merge(int r[],int s[],int x,int y,int z)
{
int i,j,k;
//第一部分的开始位置
i=x;
//第二部分的开始位置
j=y+1;
k=x;
while((i<=y)&&(j<=z))
//i和j都在两个要合并的部分中时筛选两部分中较小的元素放到数组s中
if(r[i]<=r[j])
{
s[k] = r[i];
i++;
k++;
}
else
{
s[k]=r[j];
j++;
k++;
}
while(i<=y)
s[k++]=r[i++];
while(j<=z)
s[k++]=r[j++];
return 0;
}
int sort(int r[],int s[],int j,int k)
{
int l;
int t[max];
if(j!=k){
l=(j+k)/2;
sort(r,t,j,l);
sort(r,t,l+1,k);
merge(t,s,j,l,k);
}
else
s[j]=r[j];
return 0;
}
for(i=1;i<=n;i++)
// 输入n ge数
scanf("%d",&a[i]);
//调用sort()函数进行归并排序
sort(a,a,1,n);
for(i=1;i<=10;i++)
//输出排序后的数据
printf("%4d",a[i]);
4.分析
时间复杂度:O (n logn)
5.源码
#include <stdio.h>
#define max 100
int merge(int r[],int s[],int x,int y,int z)
{
int i,j,k;
//第一部分的开始位置
i=x;
//第二部分的开始位置
j=y+1;
k=x;
while((i<=y)&&(j<=z))
//i和j都在两个要合并的部分中时筛选两部分中较小的元素放到数组s中
if(r[i]<=r[j])
{
s[k] = r[i];
i++;
k++;
}
else
{
s[k]=r[j];
j++;
k++;
}
while(i<=y)
s[k++]=r[i++];
while(j<=z)
s[k++]=r[j++];
return 0;
}
int sort(int r[],int s[],int j,int k)
{
int l;
int t[max];
if(j!=k){
l=(j+k)/2;
sort(r,t,j,l);
sort(r,t,l+1,k);
merge(t,s,j,l,k);
}
else
s[j]=r[j];
return 0;
}
int main()
{
int a[max];
int n,i;
scanf("%d",&n);
for(i=1;i<=n;i++)
// 输入n ge数
scanf("%d",&a[i]);
//调用sort()函数进行归并排序
sort(a,a,1,n);
for(i=1;i<=10;i++)
//输出排序后的数据
printf("%4d",a[i]);
return 0;
}