其实这个算法很简单,当然只要你能看下去的话,发现很好理解的这个过程:
1.对前后两部分是已经排好序的:
输入:序列A[p...r].其中子序列A[p...q]和A[q+1...r]是有序的。
首先,将A[p...q]和A[q+1..r]分别复制到序列L[1...n1]和R[1...n2]中,其中1=q-p+1,n2=r-q。然后,将i,j初始化为1,k初始化为p.比较L[i]与R[j],将较小者复制到A[k],调整i,j,k使得它们各自指向L.R和A的合适位置:若L[i]<=R[J],则i加1,否则j加1.无论如何k都要加1,循环往复直至L,R之一被扫描完。然后,将另一个序列中尚存的元素复制到A[k...r]。
算法的伪代码:
1. n1<-q-p+1
2. n2<-r-q
3. 创建数组L[1...n1]和R[1...n2]
4. for i<-1 to n1
5. do L[i]<-A[p+i-1]
6. for j<-1 to n2
7. do R[j]<-A[q+j]
8. i<-1
9. j<-1
10. k<-p
11. while i<=n1 and j<=n2
12. do if L[i]<=R[j]
13. then A[k]<-L[i]
14. i<-i+1
15. else A[k]<-R[j]
16. j<-j+1
17. k<-k+1
18. if i<n1
19. then将L[i...n1]复制到A[k...r]
20. if j<n2
21. then将R[j...n2]复制到A[k...r]
C++:
merge.h
#define _merge_h
#include<iostream>
#include<iterator>
using namespace std;
template<typename Iterator>
void merge(Iterator p,Iterator q,Iterator r){
typedef typename iterator_traits::value_type T;
long i,j,
n1=distance(p,q),
n2=distance(q,r);
T *L=new T[n1],*R=new T[n2];//分配了L,R的空间大小
copy(p,q,L);
copy(q,r,R);
Iterator k=p;
i=j=0;
while(i<n1&&j<n2)
if(L[i]<R[j])
*k=L[i];
i++;}
else
{*k=R[j];
j++;}
k++;
}
if(i<n1)
copy(L+i,L+n1,k);
if(j<n2)
copy(R+j,R+n2,k);
delete []L;
delete []R;
}
main.cpp
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<iterator>
using namespace std;
#include"merge.h"
int main(){
int a[]={1,2,5,8,9,0,3,4,6,7},i;
string b[]={"AoMen","BeiJing","ShangHai","ChongQing","TianJin","XiangGang"};
double c[]={0.5,3.7,6.3,8.5,9.2,1.7,2.3,4.1,5.9,7.4};
merge(a,a+5,a+10);
copy(a,a+10,ostream_iterator(cout," "));
cout<<endl;
merge(b,b+3,b+6);
copy(b,b+6,ostream_iterator(cout," "));
cout<<endl;
merge(c,c+5,c+10);
copy(c,c+10,ostream_iterator(cout," "));
cout<<endl;
}
JAVA:
LinearList.java
package test;
import java.util.Arrays;
public class LinearList {
public static void merge(Comparable[] a,int p,int q,int r) {//Comparable为通用数据类型
int i,j,k,
n1=q-p+1,
n2=r-q;
Comparable[] L=Arrays.copyOfRange(a, p, q+1),//将a[p...q]复制到L
R=Arrays.copyOfRange(a, q+1, r+1);//最后一个不复制
i=j=0;
k=p;
while(i<n1&&j<n2)
if(L[i].compareTo(R[j])<0) {//比较,当L[i]
a[k]=L[i];
i++;}
else
{a[k]=R[j];
j++;}
k++;
}
if(i<n1)
for(;i<n1;i++)
a[k++]=L[i];
if(j<n2)
for(;j<n2;j++)
a[k++]=R[j];
}
}
Test.java
package test;
public class Test {
public static void main(String[] args) {
Integer a[]= {1,2,5,8,9,0,3,4,6,7},i;
String b[]= {"AoMen","Beijing","ShangHai","ChongQing","TianJin","XiangGang"};
Double c[]= {0.5,3.7,6.3,8.5,9.2,1.7,2.3,4.1,5.9,7.4};
LinearList.merge(a, 0, 4, 9);
for(i=0;i<10;i++)
System.out.print(a[i]+" ");
System.out.println();
LinearList.merge(b, 0, 2, 5);
for(i=0;i<6;i++)
System.out.print(b[i]+" ");
System.out.println();
LinearList.merge(c, 0, 4, 9);
for(i=0;i<10;i++)
System.out.print(c[i]+" ");
System.out.println();
}
}
2.对前后两部分是没有排好序的:
将序列A[p...r]分为两半A[p...q]和A[q+1...r],分别递归地对这两个子序列进行排序,然后再将排好序的子序列A[p...q]和A[q+1...r]调用前面的merge.h过程进行合并成整个有序序列
算法伪代码:
1. if p
2. then q<-(p+r)/2
3. merge-sort(A,p,q)
4. merge-sort(A,q+1,r)
5. merge(A,p,q,r)
C++:
mergesort.h
#define _mergesort_h
#include "merge.h"
template<typename Iterator>
void mergesort(Iterator p,Iterator r){
int n=distance(p,r);
if(n>1){
Iterator q=p;
advance(q,n/2);//在q地址上增加距离n/2
mergesort(p,q);//地址p到地址q之间的数值进行排序,其实这里是一直进行递归得到的结果在递归回来
mergesort(q,r);
merge(p,q,r);
}
}
main.cpp
#include "mergesort.h"
#include<iostream>
#include<iterator>
using namespace std;
int main(){//会发现字符串类型的没办法运行
int a[]={5,1,9,4,6,2,0,3,8,7},i;
string b[]={"ChongQing","ShangHai","AoMen","TianJing","BeiJing","XiangGang"};
double c[]={8.5,6.3,1.7,9.2,0.5,2.3,4.1,7.4,5.9,3.7};
mergesort(a,a+10);
copy(a,a+10,ostream_iterator(cout," "));
cout<<endl;
mergesort(c,c+10);
copy(c,c+10,ostream_iterator(cout," "));
cout<<endl;
}