归并排序(Merge Sort)是利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。
1. 归并排序思想
初始序列为n个记录,可看成n个有序的子序列,每个序列长度为1,然后两辆归并,直到得到n/2或n.2+1个长度为2或1的子序列,再两两归并,······,如此重复,直到得到一个长度为n的有序序列为止。这种排序称为2-路归并排序。
算法三步骤:
设归并排序的当前区间是R[low..high]:
(1) 分解:将当前区间一分为二,即求分裂点mid=(low+high)/2。
(2) 求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;
(3) 组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。
递归的终结条件:子区间长度为1(一个记录自然有序)。
2. 2-路归并算法
- void merge(datatype s[], int low, int mid, int high)
- {
- int i = low, j = mid+1, k = 0;
- datatype *t;
- t = (datatype*) malloc ((high-low+1) * sizeof(datatype));
- if (!t)
- exit(-1);
- while (i<=mid && j<=high)
- t[k++] = s[i].key < s[j].key ? s[i++] : s[j++];
- while (i <= mid)
- t[k++] = s[i++];
- while (j <= high)
- t[k++] = s[j++];
- for (k=0,i=low; i<=high; ++k,++i) {
- s[i] = t[k];
- }
- output_list(s);
- }
- void merge_sort(datatype s[], int low, int high)
- {
- int mid;
- if (low < high) {
- mid = (low + high) / 2;
- merge_sort(s, low, mid);
- merge_sort(s, mid+1, high);
- merge(s, low, mid, high);
- }
- }
3. 算法分析
归并排序是一种稳定的排序。
存储结构要求:可用顺序存储结构。也易于在链表上实现。
时间复杂度:对长度为n的文件,需进行lgn 趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。
空间复杂度:需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。
4. 算法实现源码