1.排序思想
① 初始时,将每个记录看成一个单独的有序序列,则n个待排序记录就是n个长度为1的有序子序列;
② 对所有有序子序列进行两两归并,得到n/2(向上取整)个长度为2或1的有序子序列——一趟归并;
③ 重复② ,直到得到长度为n的有序序列为止。
上述排序过程中,子序列总是两两归并,称为2-路归并排序。其核心是如何将相邻的两个子序列归并成一个子序列。
通过先递归的分解数列,再合并数列就完成了归并排序。
2.代码
int array[1001];
int temp[1001];
void Merge(int array[],int start,int mid,int end,int temp[])
{
int i,j,k,m,n;
i=start,m=mid;
j=mid+1,n=end;
k=0;
while(i<=m && j<=n)
{
if(array[i]<=array[j])
{
temp[k]=array[i];
i++;
k++;
}
else
{
temp[k]=array[j];
j++;
k++;
}
}
while(i<=m)
{
temp[k]=array[i];
i++;
k++;
}
while(j<=n)
{
temp[k]=array[j];
j++;
k++;
}
for(i=start,j=0;i<=end;i++,j++)
{
array[i]=temp[j];
}//更新合并后 array
}
void Merge_Sort(int array[],int start,int end,int temp[])
{
int mid;
if(start<end)
{
mid=(end+start)/2;
Merge_Sort(array,start,mid,temp);//前半部分
Merge_Sort(array,mid+1,end,temp);//后半部分分治排序
Merge(array,start,mid,end,temp);//最后前后合并 完成排序
}
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
memset(array,0,sizeof(array));
memset(temp,0,sizeof(temp));
for(i=0;i<n;i++)
{
scanf("%d",&array[i]);
}
Merge_Sort(array,0,n-1,temp);
for(i=0;i<n;i++)
printf("%d ",array[i]);
printf("\n");
}
return 0;
}
3.算法分析
具有n个待排序记录的归并次数是㏒2n,而一趟归并的时间复杂度为O(n),则整个归并排序的时间复杂度无论是最好还是最坏情况均为O(n㏒2n)。大小与待排序记录空间相同,则空间复杂度为O(n)。归并排序是稳定的。