歸併排序以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];
}