【分治法】合并排序及C++源码
来源:互联网 发布:linux守护进程编写 编辑:程序博客网 时间:2024/05/22 04:40
(1)合并排序是成功应用分治技术的一个完美例子。
对于一个需要排列的数组A[0..n-1],合并排序将它一分为二:A[0..[n/2]-1]和A[[n/2]..n-1],并对每个子数组递归排序,然后把这个排好序的子数组合并为一个有序数组。
Mergesort(A[0..n-1])// 递归调用 mergesort来对数组A[0..n-1]排序// 输入:一个可排序数组A[0..n-1]// 输出:非降序排列的数组A[0..n-1]if n>1 copy A[0..[n/2]-1] to B[0..[n/2]-1] copy A[[n/2]..n-1] to C[0..[n/2]-1] Mergesort(B[0..[n/2]-1]) Mergesort(C[0..[n/2]-1]) Merge(B,C,A)
(2)对两个有序数组的合并采用以下算法:
①初始状态下,两个指针(数组下标)分别指向两个待合并数组的第一个元素。
②然后比较这两个数组的大小,将较小的元素添加到一个新创建的数组中。
③接着,被复制的数组中的指针后移,指向该较小元素的后继元素。
(上述操作一直持续到两个数组中的一个被处理完为止。然后在未处理完的数组中,剩下的元素被复制到新数组的尾部)
Merge(B[0..p-1],C[0..q-1],A[0..p+q-1])// 将两个有序数组合并为一个有序数组// 输入:两个有序数组B[0..p-1]和C[0..q-1]// 输出:A[0..p+q-1]中已经有序存放了B和C中的元素i<-0;j<-0;k<-0while i<p and j<q do if B[i]<=C[j] A[k]<-B[i];i<-i+1 else A[k]<-C[j];j<-j+1 k<-k+1if i=p copy C[j..q-1]to A[k..p+q-1]else copy B[i..p-1]to A[k..p+q-1]
(3)下图演示的是用合并排序算法对数列54,24,50,46,84,49,20,60进行排序的操作过程。
(4)合并算法效率
合并排序在最坏情况下的键值比较次数十分接近于任何基于比较的排序算法在理论上能够达到的最少次数。合并排序的主要缺点就是该算法需要线性的额外空间。虽然合并也能做到“在位”,但会导致算法过于复杂。而且,因为它的增长次数具有一个很大的常系数,所以在位的合并排序算法只具有理论上的意义。
当n>1时,C(n)=2C(n/2)+Cmerge(n),
C(1)=0,
对于最坏情况Cmerge(n)=n-1
当n>1时,Cworst(n)=nlog②n-n+1
(5)C++源码实现
#include <iostream>using namespace std;void Merge(int a[],int b[],int l,int m,int 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++]; if (i>m)for (int q=j;q<=r;q++) b[k++]=a[q]; else for (int q=i;q<=m;q++)b[k++]=a[q];}void Copy(int a[],int b[],int s,int n){ for(int i=s;i<=n;i++) a[i]=b[i];}void MergeSort(int a[],int left,int right){ int i; if(left<right) {i=(left+right)/2; int b[100]; MergeSort(a,left,i); MergeSort(a,i+1,right); Merge(a,b,left,i,right); Copy(a,b,left,right);}}int main(){ int t;cin>>t;while (t--){int a[100]; int n,i; cin>>n; for ( i=0;i<n;i++) cin>>a[i]; MergeSort(a,0,n-1); for ( i=0;i<n;i++) cout<<a[i]<<' '; cout<<endl;} return 0;}
阅读全文
2 0
- 【分治法】合并排序及C++源码
- 分治法合并排序(C++)
- 分治法合并排序
- 分治法--合并排序
- 分治法合并排序
- 分治法-----合并排序
- 分治法--合并排序
- 算法之合并排序【分治法】【C语言】
- 分治法之合并排序(C实现)
- 合并排序(分治法)
- 合并排序与分治法
- 分治法(合并排序)
- 排序3--合并(分治法)
- 分治法 合并排序递归
- 纯C语言:分治快速排序源码
- 分治法--用C++实现合并排序
- 合并排序,分治思想
- 分治合并排序
- OPENCV3.3+CUDA9.0 环境搭建若干错误总结
- rtl8188 wifi模块设置
- 关于java + websocket 使用时遇到的坑
- FeilUtils---下载文件时中文乱码
- 浏览器版本过低判断
- 【分治法】合并排序及C++源码
- 转载:Python高级特性 切片(Slice)
- 迷宫问题 非递归(java版)
- tailf、tail -f、tail -F三者区别
- 内联元素定位问题
- svg转化成canvas以便生成base64位的图片
- VirtualBox + CentOS 使用 NAT + Host-Only 方式联网
- K近邻算法线性扫描与kd树的差异
- 底部导航栏