首页 > 代码库 > 算法学习之排序算法:归并排序
算法学习之排序算法:归并排序
“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。无论是顺序存储还是链表存储结构,都可在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.csdn.net/to_be_it_1/article/details/37866391
4、http://blog.csdn.net/morewindows/article/details/6671824
算法学习之排序算法:归并排序