递归的概念:直接或间接调用自身的算法
适合递归算法的问题
1.递归函数:用函数自身给出定义的函数
2.递归结构:二叉树
递归算法设计的一般步骤
1.确定递归关系
2.确定终止条件※
3.确定递归参数
实例
1.汉诺塔问题
#include
#include
using namespace std;
int cnt=0;
void move(int id, char from, char to)
{
printf ("step %d: move %d from %c->%c\n", ++cnt, id, from, to);
}
void hanoi(int n,char a,char b,char c)
{
if(n==0)
return;
else
{
hanoi(n-1,a,c,b);
move(n,a,c);
hanoi(n-1,b,a,c);
}
}
int main()
{
int n;
cin>>n;
hanoi(n,'A','B','C');
return 0;
}
2.排列问题
#include
#include
using namespace std;
void Perm(int a[],int k,int m)
{
if(k==m)
{
for(int i=1;i<=m;i++)
{
cout<<a[i];
}
cout<<endl;
}
else
{
for(int i=k;i<=m;i++)
{
swap(a[k],a[i]);
Perm(a,k+1,m);
swap(a[k],a[i]);
}
}
}
void swap(int a,int b)
{
int r=a;
a=b;
b=r;
}
int main()
{
int n;
int a[100];
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
Perm(a,1,n);
return 0;
}
递归小结:
优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法,调试程序带来很大方便
缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储孔家都比非递归算法要多
分治所解决问题的特征
1、原问题的规模缩小到一定的程度就可以容易地解决
2.原问题可以分解为若干个规模较小的相同子问题
3.合并子问题的解可以得到原问题的解
4.子问题之间互相独立,即不同子问题不包含公共子问题
分治注意事项
1.子问题与原问题性质完全相同
2.子问题之间相互独立,可分别求解
3.最小子问题可直接求解
实例
1.数组元素升序排序
#include
using namespace std;
int a[100];
void Merge(int a[],int m,int mid,int n )
{
int i=m;
int j=mid+1;
int k=1;
int s;
int b[10]={0};
while((i<=mid)&&(j<=n))
{
if(a[i]<=a[j])
b[k++]=a[i++];
else b[k++]=a[j++];
}
while(i<=mid)
{
b[k++]=a[i++];
}
while(j<=n)
{
b[k++]=a[j++];
}
k=1;
for(int i=m;i<=n;i++)
{
a[i]=b[k++];
}
}
void Sort(int a[],int m,int n)
{
if(m<n)
{
int mid=(m+n)/2;
Sort(a,m,mid);
Sort(a,mid+1,n);
Merge(a,m,mid,n);
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
Sort(a,1,n);
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
2.求a中元素最大值
#include
using namespace std;
int Maxn(int a[],int m,int n)
{
int mid=(m+n)/2;
int max1;
int max2;
if(m==n)
return a[m];
else
{
max1=Maxn(a,m,mid);
max2=Maxn(a,mid+1,n);
if(max1>max2)
return max1;
else return max2;
}
}
int main()
{
int n;
int a[100];
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
cout<<Maxn(a,1,n);
return 0;
}
3.大整数乘法
4.矩阵乘法
5.棋盘覆盖问题
#include
#include
#include
using namespace std;
int a[100][100];
int tile=1;
void ChessBoard(int tr,int tc,int dr,int dc,int sizea)
{
if(sizea==1)
return;
int t=tile++;
int s;
s=sizea/2;
if(dr<tr+s&&dc<tc+s)
ChessBoard(tr,tc,dr,dc,s);
else
{
a[tr+s-1][tc+s-1]=t;
ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
}
if(dr<tr+s&&dc>=tc+s)
{
ChessBoard(tr,tc+s,dr,dc,s);
}
else
{
a[tr+s-1][tc+s]=t;
ChessBoard(tr,tc+s,tr+s-1,tc+s,s);
}
if(dr>=tr+s&&dc<tc+s)
{
ChessBoard(tr+s,tc,dr,dc,s);
}
else
{
a[tr+s][tc+s-1]=t;
ChessBoard(tr+s,tc,tr+s,tc+s-1,s);
}
if(dr>=tr+s&&dc>=tc+s)
{
ChessBoard(tr+s,tc+s,dr,dc,s);
}
else
{
a[tr+s][tc+s]=t;
ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
}
}
int main()
{
int n;
int ki,kj;
int k;
int t;t=1;
cin>>n>>ki>>kj;