分治法的基本思想
将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
分治法的求解过程:
①划分:将整个问题划分为多个子问题,子问题与原问题有相同的类型。
②求解:求解各个子问题(可以使用递归反复调用)
③合并:合并所有子问题的解,形成原问题的解。
分治算法经典例题1:二分查找
给定一个有序数组,查找某数是否在这个有序数组中。
#include<iostream>
using namespace std;
void search(int a[],int L,int R,int m)
{
if(L>R)
{
cout<<"can not find this number"<<endl;
return ;
}
int mid=(L+R)/2;
if(a[mid]==m)
{
cout<<"find this number:"<<m<<endl;
return ;
}
else if(a[mid]>m)
{
search(a,L,mid,m);
}
else
{
search(a,mid+1,R,m);
}
}
int main()
{
int i,n,m;
cin>>n;
int a[n];
for(i=0;i<n;i++)
{
cin>>a[i];
}
cin>>m;
search(a,0,n-1,m);
return 0;
}
结果展示:
分治算法经典例题2:求数组中的最大最小值
#include<iostream>
using namespace std;
void fx(int *a,int L,int R,int &max,int &min)
{
if(R-L==0||R-L==1)//递归出口
{
min=a[L]<a[R]?a[L]:a[R];
max=a[L]>a[R]?a[L]:a[R];
return ;
}
int temp=(R+L)/2;
int max1,max2,min1,min2;
fx(a,L,temp,max1,min1);//分
fx(a,temp+1,R,max2,min2);
max=max1>max2?max1:max2;//治
min=min1<min2?min1:min2;
return ;
}
int main()
{
int n,i;
cin>>n;
int *a=new int[n];
for(i=0;i<n;i++)
{
cin>>a[i];
}
int max,min;
fx(a,0,n-1,max,min);
cout<<"max="<<max<<"\tmin="<<min<<endl;
return 0;
}
结果展示:
分治算法经典例题3:快速排序
#include<iostream>
using namespace std;
int partition(int a[],int m,int n)
{
int L=m;
int R=n;
int k=a[L];
int temp;
while(L<R)
{
L++;
while(a[L]<=k)
{
L++;
}
// R--;
while(a[R]>k)
{
R--;
}
if(L<R)
{
temp=a[L];
a[L]=a[R];
a[R]=temp;
}
}
a[m]=a[R];
a[R]=k;
return R;
}
int* Q_sort(int a[],int m,int n)//快速排序
{
if(m<n)
{
int j=partition(a,m,n);
Q_sort(a,m,j-1);
Q_sort(a,j+1,n);
}
return a;
}
int main()
{
int n,i;
cin>>n;
int a[n];
for(i=0;i<n;i++)
{
cin>>a[i];
}
Q_sort(a,0,n-1);
for(i=0;i<n;i++)
{
cout<<a[i]<<"\t";
}
cout<<"\n";
return 0;
}