分治法:将原有问题分解为几个规模较小但类似于原有问题的子问题,递归地求解这些子问题,然后在合并这些子问题的解来建立原有问题的解。
分治模式在每层递归时都有三个步骤:
分解,解决,合并。
归并排序的算法就是典型的分治法。
分解:分解待排序的n个元素序列成n/2的两个子序列。
解决:使用归并排序递归地排序两个子序列。
合并:合并两个已排序的子序列以产生已排序的答案。
归并排序代码:
void merge(int a[],int p,int q,int r)
{
int L[1000],R[100];
int n1=q-p+1;
int n2=r-q;
int i=0,j=0;
for(i;i<n1;i++)
{
L[i]=a[p+i];
}
for (j;j<n2;j++)
{
R[j]=a[q+j+1];
}
L[n1]=R[n2]=100000;
int k=p;
i=j=0;
for(k;k<=r;k++)
{
if(L[i]<=R[j])
{
a[k]=L[i];
i++;
}
else
{
a[k]=R[j];
j++;
}
}
}
void merge_Sort(int a[],int p,int r)
{
if (p<r)
{
int q=(p+r)/2;
merge_Sort(a,p,q);
merge_Sort(a,q+1,r);
merge(a,p,q,r);
}
}
int main()
{
int a[1000];
int n;
cin>>n;
for (int i = 1; i <=n; i++)
{
cin>>a[i];
}
merge_Sort(a,1,n);
for (int i = 1; i <=n; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
分析分治算法:
T(n)为运行时间。
假设把原问题分解成a个子问题,每个子问题的规模是原问题的1/b。
那么得到递归式
T(n)=o(1) n<=c
aT(n/b)+D(n)+C(n) 其他
D(n)为分解子问题所需的时间,C(n)合并子问题所需的时间
c为常量。