合并排序算法
来源:互联网 发布:廖雪峰python 编辑:程序博客网 时间:2024/06/04 18:16
算法思想
合并排序算法是用分治策略实现对n个元素进行排序的算法。其基本思想是:将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成所要求的排好序的集合。合并算法可递归描述如下:
void MergeSort(int a[], int left, int right){ if (left < right) { //至少还有两个元素 int mid = (left + right) / 2; //取中点 MergeSort(a, left, mid); MergeSort(a, mid+1, right); Merge(a, b, left, mid, right); //合并到数组b Copy(a, b, left, right); //复制回数组a }}
其中,算法Merge合并两个排好序的数组段到一个新的数组b中,然后由Copy将合并后的数组段再复制回数组a中。Merge和Copy都可在O(n)时间内完成,因此合并排序算法对n个元素进行排序,在最坏情况下所需的计算时间T(n)满足:
解此递归方程可得T(n) = O(nlgn).由于排序问题的计算时间下界为
实现代码
#include <stdio.h>#include <stdlib.h>void MergeSort(int a[], int left, int right);void Merge(int a[], int b[], int l, int m, int r);void Copy(int a[], int b[], int s, int e);int main(){ int i, n; printf("please enter array size:"); scanf("%d", &n); int a[n]; printf("please enter number:"); for (i = 0; i < n; i++) scanf("%d", &a[i]); printf("array:\n"); for (i = 0; i < n; ++i) printf("%4d", a[i]); printf("\n"); MergeSort(a, 0, n-1); printf("sort array:\n"); for (i = 0; i < n; ++i) printf("%4d", a[i]); printf("\n"); return 0;}void MergeSort(int a[], int left, int right){ //合并排序 if (left < right) { //至少还有两个元素 int n = right - left + 1; //b数组大小 int b[n]; //下标从0开始 int mid = (left + right) / 2; //取中点 MergeSort(a, left, mid); //排序左边部分 MergeSort(a, mid + 1, right); //排序右边部分 Merge(a, b, left, mid, right); //合并到数组b Copy(a, b, left, right); //复制回数组a }}void Merge(int a[], int b[], int l, int m, int r){ //把a数组排好序的左右两部分合并到b数组中 int i, j, k; i = l; //i指向a左边起始下标 j = m + 1; //j指向a右边起始下标 k = 0; //k指向b数组起始下标 while (i <= m && j <= r) { if (a[i] < a[j]) b[k++] = a[i++]; else b[k++] = a[j++]; } /*把数组剩余的部分复制到b中*/ while (i <= m) b[k++] = a[i++]; while (j <= r) b[k++] = a[j++];}void Copy(int a[], int b[], int s, int e){ //b数组复制到a数组 int i, j; for (i = s, j= 0; i <= e; ++i, ++j) a[i] = b[j];}
算法改进
对于算法MergeSort,还可以从分支策略的机制入手,容易消除算法中的递归。事实上,算法MergeSort的递归过程只是将待排序集合一分为二,直至待排序集合只剩下一个元素为止,然后不断合并两个排好序的数组段。按此机制,可以首先将数组a中相邻元素两两配对。用合并算法将他们排序,构成n/2组长度为2的排好序的子数组段,然后将他们排序成长度为4的排好序的子数组段,如此继续下去,直至整个数组排好序。
按此思想,消去递归后的合并排序算法可描述如下:
void MergeSort(int a[], int n){ int b[n]; int s = 1; while (s < n) { MergeSort(a, b, s, n); //合并到数组b s += s; MergeSort(b, a, s, n); //合并到数组a s += s; }}
其中MergePass用于合并排好序的相邻数组段。具体的合并算法由Merge来实现。对于MergePass函数,合并排好序的相邻数组段。到最后,可能剩下元素不足2s个,对于大于s个元素和小于等于s个元素分别采用不同的处理方式。具体见函数定义。
对于函数Merge,与之前大致相同,只是数组b下标从l开始,而之前的Merge函数,下标从0开始。
改进后的代码
/***合并排序——非递归版本*/#include <stdio.h>#include <stdlib.h>void MergeSort(int a[], int n);void MergePass(int a[], int b[], int s, int n);void Merge(int a[], int b[], int l, int m, int r);int main(){ int i, n; printf("please enter array size:"); scanf("%d", &n); int a[n]; printf("please enter number:"); for (i = 0; i < n; i++) scanf("%d", &a[i]); printf("array:\n"); for (i = 0; i < n; ++i) printf("%4d", a[i]); printf("\n"); MergeSort(a, n); printf("sort array:\n"); for (i = 0; i < n; ++i) printf("%4d", a[i]); printf("\n"); return 0;}void MergeSort(int a[], int n){ //合并排序 int b[n]; int s = 1; while (s < n) { MergePass(a, b, s, n); //合并到数组b s += s; MergePass(b, a, s, n); //合并到数组a s += s; }}void MergePass(int a[], int b[], int s, int n){ int i = 0, j; while (i <= n - 2 * s) { //max(i) 到 n-1的闭区间大小为2s Merge(a, b, i, i+s-1, i+2*s-1); //合并大小为s的相邻2段子数组 i = i + 2*s; } //剩下的运算个数少于2s个 if (i + s < n) { //至少还有s+1个元素 Merge(a, b, i, i+s-1, n-1); } else { //最多剩下s个元素 for (j = i; j < n; j++) b[j] = a[j]; }}void Merge(int a[], int b[], int l, int m, int r){ //合并a[l:m]和a[m+1:r]到b[l:r] int i = l, j = m+1, k = l; while (i <= m && j <= r) { if (a[i] <= a[j]) b[k++] = a[i++]; else b[k++] = a[j++]; } /*把数组剩余的部分复制到b中*/ while (i <= m) b[k++] = a[i++]; while (j <= r) b[k++] = a[j++];}
0 0
- 排序算法---合并排序
- 排序算法-合并排序
- 合并排序算法
- 合并排序算法
- 算法-----合并排序
- java 合并排序算法
- 合并排序算法
- 合并排序算法
- 合并排序算法
- 合并排序 算法实现
- c++合并排序算法
- 合并排序算法
- javascript 合并排序算法
- 合并排序算法
- 合并排序算法
- 算法之合并排序
- 合并排序算法
- 合并排序算法
- 数据压缩原理与应用 实验二 图像文件的读写和转换(BMPtoYUV)
- leetcodeOJ 537. Complex Number Multiplication
- Mac安装双系统Windows步骤问题总结
- Android View事件的分发机制
- CUDA-Ray Tracing
- 合并排序算法
- HDU 5066 Harry And Physical Teacher
- 二叉树的最大深度
- 无符号数 0 ( 0 -1 == -1 ?)
- html--1.html基础
- Java8新特性之默认方法
- Boyer-Moore算法Java实现
- 前端脚本化http
- [JZOJ5012]远行