归并排序的实现:
基本思路就是将区间逐渐变小,然后 将区间内的数,按照顺序依次放入TmpA数组中。归并排序相比于快排需要耗费更多的空间,但是它最慢的时间复杂度也是O(nlogn),但是在实际做题的过程中快排基本够用
void Merge(ElementType A[],ElementType TmpA[],int L,int R,int RightEnd)
{
//将有序的A[L]~A[R-1]和A[R]~A[RightEnd]归并成一个有序序列
int LeftEnd,NumElements,Tmp;
int i;
LeftEnd=R-1; //左边终点位置
Tmp=L; //有序序列的起始位置
NumElements=RightEnd-L+1;
while(L<=LeftEnd&&R<=RightEnd)
{
if(A[L]<=A[R])
{
TmpA[Tmp++]=A[L++]; //将左边元素复制到TmpA
}
else
{
TmpA[Tmp++]=A[R++]; //将右边元素复制到TmpA
}
}
while(L<=LeftEnd)
{
TmpA[Tmp++]=A[L++]; //直接复制左边剩下的
}
while(R<=RightEnd)
{
TmpA[Tmp++]=A[R++]; //直接复制右边剩下的
}
for(i=0; i<NumElements; i++,RightEnd--)
{
A[RightEnd]=TmpA[RightEnd]; //将有序的TmpA[]复制回A[]
}
}
void Msort(ElementType A[],ElementType TmpA[],int L,int RightEnd)
{
//核心递归排序函数
int Center;
if(L<RightEnd)
{
Center=(L+RightEnd)/2;
Msort(A,TmpA,L,Center); //递归解决左边
Msort(A,TmpA,Center+1,RightEnd); //递归解决右边
Merge(A,TmpA,L,Center+1,RightEnd); //合并两段有序序列
}
}
void MergeSort(ElementType A[],int N)
{//归并排序,适用于下标范围0~N-1,因为Msort函数原因,如果N==1,需要特判一下,如果需要对另一个范围区间内的数据排序,可以直接调用Msort指定排序区间,这个函数左右端点都包括在内
ElementType *TmpA;
TmpA=(ElementType *)malloc(N*sizeof(ElementType));
if(TmpA!=NULL)
{
if(N==1)
{
TmpA[0]=A[0];
}
else
{
Msort(A,TmpA,0,N-1);
}
for(int i=0;i<N;i++)
{
printf("%d ",TmpA[i]);
}
free(TmpA);
}
else
{
printf("空间不足");
}
}