归并排序
基本思想:al.....am.....ar -> 两边排序 然后再归并
归并工作量 最好为 n/2,最坏为 n-1 => T(n) = 2* T(n/2)+θ(n* logn)=>由主定理 T(n) = θ(n* logn)
//归并
template<class T>
merge(T *a,int l,int m,int r,T *c)
{
//[al].....a[m] || a[m+1].....a[r]
//c[l].........c[m].....c[r]
int i = l,k = l,j = m+1;
while(i<=m&&j<=r)
{
if(a[i]<a[j])
{
c[k++] = a[i++];
}else{
c[k++] =a[j++];
}
}
if(i>m)//左侧归并完毕
{
while(j<=r)
{
c[k+1] = a[j++];
}
}else{
while(i<=m)
{
c[k++] = a[i++];
}
}
}
template<class T>
void Copy(T *c,int l,int r,T *a)
{
//c[l].....c[r] 复制到 a[l].....a[r]
for(int i = l;i<=r;i++)
{
a[i] = c[i];
}
}
//排序算法
template<class T>
MergeSort(T *a,int l,int r,T *c)
{
if(r<=l) return ;
//以下为l<r
int m = ( l + r )/2;
//[l,m],[m+1,r]
MergeSort(a,l,m,c);
MergeSort(a,m+1,r,c);
Merge(a,l,m,r,c); //有比较,最坏n-1 ,最好 n/2
Copy(c,l,r,a); //无比较工作量,仅复制
}
//用法
int n = 100 0000;
double *a =new double[n];
for(int i = 0;i<n;i++)
{
a[i] = Random();
}
double *c =new double[n];//排序移动方向
MergeSort(a,0,n-1,c);
delete[] c;//清除移动方向
//已排序 a[0]<=...a[n-1]
输出a[i]...
delete[] a;