“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。无论是顺序存储还是链表存储结构,都可在O(m+n)的时间量级上实现。
归并排序又是一类不同的排序方法。假设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个为2或1的有序子序列;再两两归并,....... ,如此重复,直至得到一个长度为n的有序序列为止。
初始关键字:[49] [38] [65] [97] [76] [13] [27]
A A B B C C D
一趟归并后:[38 49] [65 97] [13 76] [27]
A A B B
二趟归并后:[38 49 65 97] [13 27 76]
A A
三趟归并后:[13 27 38 49 65 76 97]
从上面归并排序算法的示例可以看出,该算法时采用分治法的一个典型应用。
实现示例(C语言描述):
void Merge(ElementType array[], ElementType TmpArray[], int lpos, int rpos, int rightend)
{
if(array == NULL || TmpArray == NULL)
return;
int i, leftend, numelements, tmppos;
leftend = rpos - 1;
tmppos = lpos;
numelements = rightend - lpos + 1;
/*main loop*/
while(lpos <= leftend && rpos <= rightend)
if(array[lpos] <= array[rpos])
TmpArray[tmppos++] = array[lpos++];
else
TmpArray[tmppos++] = array[rpos++];
while(lpos <= leftend)
TmpArray[tmppos++] = array[lpos++];
while(rpos <= rightend)
TmpArray[tmppos++] = array[rpos++];
for(i = 0; i < numelements; i++, rightend--)
array[rightend] = TmpArray[rightend];
}
void MSort(ElementType array[], ElementType TmpArray[], int left, int right)
{
if(array == NULL || TmpArray == NULL || left < 0 || right < 0)
return ;
int center;
if(left < right){
center = (left + right) / 2;
MSort(array, TmpArray, left, center);
MSort(array, TmpArray, center + 1, right);
Merge(array, TmpArray, left, center + 1, right);
}
}
void Mergesort(ElementType array[], int length)
{
if(array == NULL || length < 0)
return;
ElementType *TmpArray;
TmpArray = (ElementType *)malloc(length * sizeof(ElementType));
if(TmpArray == NULL){
fprintf(stderr, "no space.\n");
return;
}
MSort(array, TmpArray, 0, length - 1);
free(TmpArray);
return;
}
从上面给出的算法实现可以看出,实现归并排序需要和待排记录等数量的辅助空间,其时间复杂度为O(nlogn)。与快速排序和堆排序相比,归并排序的最大特点是:它是一种稳定的排序方法。另外注意,上面实现的归并排序使用了递归的方法,递归形式上比较简单,但其实用性很差。可使用费递归形式的算法实现。
参考文献:
1、《数据结构与算法分析——C语言描述》Mark Allen Weiss著
2、《数据结构(C语言描述)》 严蔚敏 吴伟东 编著
3、http://blog.youkuaiyun.com/to_be_it_1/article/details/37866391
4、http://blog.youkuaiyun.com/morewindows/article/details/6671824