归并排序以O(NlogN)最坏时间运行,而说使用的比较次数几乎是最优的,它是递归算法的一个很好的实现。这个算法中基本的操作是合并俩个已排序的表,因为这俩个表是已排序的,说以如果将输出放到第三个表中时该算法可以通过对输入数据一趟排序来完成。基本的合并算法是取俩个输入数组A和B,一个输出数组C,以及三个计数器Aptr,Bptr,Cptr,它们的位置于对应数组的开端。A[Aptr]和B[Bptr]中的较小者被拷贝到C中的下一个位置,相关的计数器向前推进一步,当有一个输入表用完,则将另一个表中剩余部分拷贝到C中。
void Msort(int a[],int temp[],int begin,int end)
{
int center;
if(begin<end)
{
center=(begin+end)/2;
Msort(a,temp,begin,center);
Msort(a,temp,center+1,end);
merge(a,temp,begin,center+1,end);
}
}
void mergeSort(int a[],int length)
{
int *TempArray;
TempArray=(int *)malloc(length*sizeof(int));
if(!TempArray)
{
printf("out of space\n");
exit(-1);
}
Msort(a,TempArray,0,length-1);
free(TempArray);
}
void merge(int a[],int temp[],int left,int right,int rightend)
{
int leftend,i;
int Apos,Bpos,temppos=left;
leftend=right-1;
Apos=left; //俩计数器的起始位置
Bpos=right;
while(Apos<=leftend&&Bpos<=rightend) //当输入数组都没有完成
{
if(a[Apos]<=a[Bpos])
{
temp[temppos]=a[Apos];
Apos++;
temppos++;
}
else if(a[Apos]>a[Bpos])
{
temp[temppos]=a[Bpos];
Bpos++;
temppos++;
}
else //相等就一起拷贝过去
{
temp[temppos]=a[Apos];
temp[temppos+1]=a[Bpos];
temppos+=2;
Apos++;
Bpos++;
}
}
//将剩下的全都拷贝到C中
while(Apos<=leftend)
temp[temppos++]=a[Apos++];
while(Bpos<=rightend)
temp[temppos++]=a[Bpos++];
//把最终的数组拷贝到原来的数组中
for(i=0;i<temppos;i++)
a[i]=temp[i];
}