合并排序算法是用分治策略实现对n个元素进行排序的算法,其基本思想是:将待排序元素分成大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成要求的排好序的集合。
《计算机算法算法设计与分析》22页。
#include <stdio.h>
#include <stdlib.h>
int a[10001],b[10001];
void Merge(int a[],int b[],int l,int m,int r)
{
int i=l,j=m+1,k=l;
while(i<=m&&j<=r)
{
if(a[i]<a[j])
b[k++]=a[i++];
else b[k++]=a[j++];
}
if(i>m)
{
while(j<=r)
b[k++]=a[j++];
}
else
{
while(i<=m)
b[k++]=a[i++];
}
}
void Copy(int a[],int b[],int left,int right)
{
int i;
for(i=left;i<=right;i++)
{
a[i]=b[i];
}
}
void MergeSort(int a[],int left,int right)
{
if(left<right)
{
int i=(left+right)/2;
MergeSort(a,left,i);
MergeSort(a,i+1,right);
Merge(a,b,left,i,right);
Copy(a,b,left,right);
}
}
int main( )
{
int n,i;
scanf("%d",&n);
for(i=1; i<=n; i++)
scanf("%d",&a[i]);
MergeSort(a,1,n);
for(i=1; i<=n; i++)printf("%d ",b[i]);
return 0;
}
对于MergeSort,还可以改进,可以消除算法中的递归,消除递归后的算法为:
#include <stdio.h>
#include <stdlib.h>
int a[10001],b[10001];
void Merge(int a[],int b[],int l,int m,int r)
{
int i=l,j=m+1,k=l;
while(i<=m&&j<=r)
{
if(a[i]<a[j])
b[k++]=a[i++];
else b[k++]=a[j++];
}
if(i>m)
{
while(j<=r)
b[k++]=a[j++];
}
else
{
while(i<=m)
b[k++]=a[i++];
}
}
void MergePass(int a[],int b[],int s,int n)
{
int i=0,j;
while(i<=n-2*s)
{
Merge(a,b,i,i+s-1,i+2*s-1);
i=i+2*s;
}
if(i+s<n)
Merge(a,b,i,i+s-1,n-1);
else
{
for(j=i; j<=n-1; j++)
b[j]=a[j];
}
}
void MergeSort(int a[],int n)
{
int s=1;
while(s<n)
{
MergePass(a,b,s,n);
s=s+s;
MergePass(b,a,s,n);
s=s+s;
}
}
int main( )
{
int n,i;
scanf("%d",&n);
for(i=0; i<n; i++)
scanf("%d",&a[i]);
MergeSort(a,n);
for(i=0; i<n; i++)printf("%d ",b[i]);
return 0;
}