【归并排序】
来源:互联网 发布:图标上下不停跳动js 编辑:程序博客网 时间:2024/06/18 08:46
归并排序(Merging Sort)
归并排序就是将两个或两个以上的有序表合并成一个有序表的过程。将两个有序表合并成一个有序表的过程称为2-路归并。
归并排序算法的思想是:
假设初始序列含有n个记录,则可看成n个有序的子序列,每个字序列的长度为1,然后两两归并,得到[n/2]个长度为2或1的有序子序列;再两两归并,...,如此重复,直到一个长度为n的有序序列为止。
例 已知待排序记录的关键字序列为{49,38,65,97,76,13,27},给出2-路归并排序法进行排序的过程
2-路归并排序中的核心操作是,将待排序序列中前后相邻的两个有序序列归并为一个有序序列。
相邻两个有序子序列的归并
[算法思想]
设两个有序表存放在同一数组中相邻的位置上:R[low..mid]和R[mid+1..high],每次分被从两个表中取出一个记录进行关键字的比较,将较小者放入T[low..high]中,重复此过程,直至其中一个表为空,最后将另一非空表中余下的部分直接复制到T中。[算法描述]
void Merge(int R[],int T[],int low,int mid,int high) {/*将有序表R[low..mid]和R[mid+1..high]归并为有序表T[low..high]*/int i=low;int j=mid+1;int k=low;while(i<=mid&&j<=high) /*将R中记录由小到大的并入T中*/{if(R[i]<=R[j])T[k++]=R[i++];else T[k++]=R[j++];}while(i<=mid) T[k++]=R[i++];/*将剩余的R[i..mid]复制到T中*/while(j<=high) T[k++]=R[j++];/*将剩余的R[j..high]复制到T中*/ }
假设每个子序列的长度为h,则一趟归并排序需要调用[n/2h]次算法merge进行两两归并,得到前后相邻、长度为2h的有序段,整个归并排序序进行[log2n]趟。与快速排序类似,2-路归并排序也可以利用划分为子序列的方法递归实现。首先把整个待排序序列划分为两个长度大致相等的子序列,对这两个子序列分别递归地进行排序,然后再把他们归并。典型的分治思想,分解,解决,合并。
归并排序
[算法思想]
2-路归并排序将R[low..high]中的记录归并排序后放入T[low..high]中。当序列长度等于1时,递归结束,否则:
1)将当前序列一分为二,求出分裂点mid=(low+high)/2;
2)对子序列R[low..mid]递归,进行归并排序,结果放入S[low..mid]中。
3)对子序列R[mid+1..high]递归,进行归并排序,结果放入S[mid+1..high]中。
4)调用算法Merge,将有序的两个子序列S[low..mid]和S[mid+1..high]归并为一个有序的序列T[low..high];
[算法描述]void MSort(int R[],int T[],int low,int high){/*R[low..high]归并排序后放入T[low..high]中*/int mid=0;int S[101]; /*辅助数组*/if(low==high)T[low]=R[low];else{mid=(low+high)/2; /*将当前序列一分为二,求出分裂点mid*/MSort(R,S,low,mid); /*对子序列R[low..mid]递归归并排序,结果放入S[low..mid]*/MSort(R,S,mid+1,high); /*对子序列R[mid+1..high]递归归并排序,结果放入S[mid+1..high]*/Merge(S,T,low,mid,high); /*将S[low..mid]和S[mid+1..high]归并到T[low..high]*/}} void MergeSort(int L[],int n) { MSort(L,L,1,n); }[算法分析]
1)时间复杂度
当有n个记录时,需进行[log2n]趟归并排序,每一趟归并,其关键字比较次数不超过n,元素移动次数都是n,因此,归并排序的时间复杂度为O(nlog2n)。
2)空间复杂度
用顺序表实现归并排序时,需要和待排序记录个数相等的辅助存储空间,所以空间复杂度为O(n);
[完整代码]
#include<iostream>using namespace std;void Merge(int R[],int T[],int low,int mid,int high) {/*将有序表R[low..mid]和R[mid+1..high]归并为有序表T[low..high]*/int i=low;int j=mid+1;int k=low;while(i<=mid&&j<=high) /*将R中记录由小到大的并入T中*/{if(R[i]<=R[j])T[k++]=R[i++];else T[k++]=R[j++];}while(i<=mid) T[k++]=R[i++];/*将剩余的R[i..mid]复制到T中*/while(j<=high) T[k++]=R[j++];/*将剩余的R[j..high]复制到T中*/ }void MSort(int R[],int T[],int low,int high){/*R[low..high]归并排序后放入T[low..high]中*/int mid=0;int S[101]; /*辅助数组*/if(low==high)T[low]=R[low];else{mid=(low+high)/2; /*将当前序列一分为二,求出分裂点mid*/MSort(R,S,low,mid); /*对子序列R[low..mid]递归归并排序,结果放入S[low..mid]*/MSort(R,S,mid+1,high); /*对子序列R[mid+1..high]递归归并排序,结果放入S[mid+1..high]*/Merge(S,T,low,mid,high); /*将S[low..mid]和S[mid+1..high]归并到T[low..high]*/}} void MergeSort(int L[],int n) { MSort(L,L,1,n); /*注意排序的起始位置是1*/ } int main() { int ans[5]={0,7,2,36,1}; MergeSort(ans,4); for(int i=1;i<=4;i++) cout<<ans[i]<<" "; return 0; }[运行结果]
- 归并排序-归并排序
- 归并和归并排序
- 归并与归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 排序::归并
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 【剑指offer】之第一个只出现一次的字符
- javascript DOM
- 让PHP 7达到最高性能的几个Tips
- 直接操作USRP属性树
- UART0串口编程系列 UART0串口编程之在UC/OS—II中遭遇的危机
- 【归并排序】
- OPENCV中使用SVM训练并识别车牌的初步应用
- iOS框架介绍——N&O&P字头
- Dead Reckoning - 航位推测法
- 类的再生
- Lucene学习(一):全文检索的基本原理
- 将iframe设置为可编辑状态
- 让后台服务不被杀———电话录音
- 【详解】Python脚本转可执行文件