归并排序原理很简单,是将两个或两个以上的有序表组合成一个新的有序表。
假设初始序列有n个记录,则可看成n个有序的子序列,每个子序列长度为1,然后两两归并,得到n/2个长度为2或1(怎么?为什么有1的可能,想想知道吧,如果是奇数序列呢)的有序子序列;再两两归并,.........如此重复,直至得到一个长度为n的有序序列为止,这种排序称为2-路归并排序。如果还不明白。。。就看看如下图:
49 38 65 97 76 13 27
| | | | | | |
------- -------- -------- |
| | | |
38 49 65 97 13 76 27 一趟归并排序后
| | | | | | |
------------------- --------------
| |
38 49 65 97 13 27 76 二趟归并排序后
| | | | | | |
--------------------------------------------
|
13 27 38 49 65 76 97 三趟归并排序
代码贴上,从下面代码可以看出,实现归并排序需要和待排纪录等数量的辅助空间,其时间复杂度为O(nlog2n)。与快速排序和堆排序相比,归并排序最大的特点是:它是稳定排序,但是一般的情况下。很少利用2-路归并排序进行内部排序。
/****************************************************************
Function: sort_Merge
Date: 2010-06-14
Author: Robbie
Description: 合并两个序列
Input: INT *piData 待排序的数列
INT iNum 数列个数
Output: None
Return: None
Modify:
*****************************************************************/
STATIC VOID sort_Merge(IN INT *piData, IN INT iLow, IN INT iMid, IN INT iHigh)
{
INT i, j, k;
INT *piTmp = (INT *)malloc((UINT)(iHigh - iLow + 1) * sizeof(INT));
if (NULL == piTmp)
{
return;
}
for (i = iLow, j = iMid + 1, k = 0; (i <= iMid) && (j <= iHigh); k++)
{
if (piData[i] < piData[j]) /* 将数从小到大放入piTmp中 */
{
piTmp[k] = piData[i++];
}
else
{
piTmp[k] = piData[j++];
}
}
while (i <= iMid) /* 将第一个序列剩余的数拷贝到piTmp */
{
piTmp[k++] = piData[i++];
}
if (j <= iHigh) /* 将第二个序列剩余的数拷贝到piTmp */
{
piTmp[k++] = piData[j++];
}
for (i = iLow; i <= iHigh; i++) /* 将排好序的数列拷贝回原数列 */
{
piData[i] = piTmp[i - iLow];
}
free(piTmp);
return;
}
/****************************************************************
Function: sort_MergeRecur
Date: 2010-06-14
Author: Robbie
Description: 归并排序
Input: INT *piData 待排序的数列
INT iNum 数列个数
Output: None
Return: None
Modify:
*****************************************************************/
STATIC VOID sort_MergeRecur(IN INT *piData, IN INT iFirst, IN INT iLast)
{
INT iMid = 0;
if (iFirst < iLast)
{
iMid = (iFirst + iLast)/2;
sort_MergeRecur(piData, iFirst, iMid);
sort_MergeRecur(piData, iMid + 1, iLast);
sort_Merge(piData, iFirst, iMid, iLast);
}
return;
}
/****************************************************************
Function: SORT_Merge
Date: 2010-06-14
Author: Robbie
Description: 归并排序
Input: INT *piData 待排序的数列
INT iNum 数列个数
Output: None
Return: None
Modify:
*****************************************************************/
VOID SORT_Merge(IN INT *piData, IN INT iNum)
{
if ((iNum <= 1) || (NULL == piData))
{
return;
}
sort_MergeRecur(piData, 0, iNum -1);
return;
}