1. 算法概述
归并排序(Merging Sort)是又一类不同的排序方法。“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表,无论是顺序存储结构还是链表存储结构,都可在O(m+n)的时间量级上实现。利用归并的思想容易实现排序。假设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列;再两两归并,......,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2-路归并排序。
下图是两路归并的一个例子。
2-路归并排序中的核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列。
2. 算法分析
实现归并排序需和待排记录等数量的辅助空间,其时间复杂度为
O(nlogn)。与快速排序和堆排序相比,归并排序的最大特点是,它是一种稳定的排序方法。但在一般情况下,很少利用2-路归并排序进行内部排序。
3. 算法实现
/*********************************************************************************
*Copyright(C),Your Company
*FileName: main.cpp
*Author: Huangjh
*Version:
*Date: 2017-12-24
*Description: 归并排序的实现
*Others:
**********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void Merge(int *pBuffer, int iLow, int iMid, int iHigh)
{
//将2个有序的子序列pBuffer[iLow,...,iMid]和pBuffer[iMid+1,...,iHigh]
int iFirstSequence = iLow; //子序列1的下标
int iSecondSequence = iMid + 1; //子序列2的下标
int iMerger = 0; //新序列的下标
int *pTemp = (int *)malloc((iHigh - iLow + 1) * sizeof(int));
if (pTemp == NULL)
{
return;
}
//对比两个子序列中较小的放到归并后的序列中去
while (iFirstSequence <= iMid && iSecondSequence <= iHigh)
{
pTemp[iMerger++] = (pBuffer[iFirstSequence] > pBuffer[iSecondSequence]) ? pBuffer[iSecondSequence++] : pBuffer[iFirstSequence++];
}
//剩下子序列1
while (iFirstSequence <= iMid)
{
pTemp[iMerger++] = pBuffer[iFirstSequence++];
}
//剩下子序列2
while (iSecondSequence <= iHigh)
{
pTemp[iMerger++] = pBuffer[iSecondSequence++];
}
int i;
for (iMerger = 0, i = iLow; i <= iHigh; iMerger++, i++)
{
pBuffer[i] = pTemp[iMerger];
}
return;
}
void MergeSort(int *pBuffer, int iLow, int iHigh)
{
int iMid = 0;
if (iLow < iHigh)
{
iMid = (iLow + iHigh) / 2;
MergeSort(pBuffer, iLow, iMid); //对pBuffer[iLow,...,iMid]进行递归排序,使之成为有序子序列
MergeSort(pBuffer, iMid + 1, iHigh); //对pBuffer[iMid+1,...,iHigh]进行递归排序,使之成为有序子序列
Merge(pBuffer, iLow, iMid, iHigh); //归并两个子序列
}
}
int main(void)
{
int szBuffer[] = { 49, 38, 65, 97, 76, 13, 27, 49 };
MergeSort(szBuffer, 0, sizeof(szBuffer) / sizeof(szBuffer[0]) - 1);
printf("归并排序后的输出:\r\n");
for (int i = 0; i < sizeof(szBuffer) / sizeof(szBuffer[0]) - 1; i++)
{
printf("%d ", szBuffer[i]);
}
printf("\r\n");
return 0;
}
运行结果如下所示:
归并排序后的输出:
13 27 38 49 49 65 76