递归调用是一种直接或者间接地调用自身的算法。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,递归通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。用递归思想写出的程序往往十分简洁易懂。
递归程序在执行过程中一般有如下模式:
1将调用程序的返回地址、相应的调用前的变量都保存在系统堆栈中;
2执行被调用的函数;
3若满足退出递归的条件,则退出递归,并从栈顶上弹回返回地址、取回保存起来的变量值,继续沿着返回地址,向下执行程序;
4否则继续递归调用,只是递归调用的参数发生变化:增加一个量或减少一个量,重复执行直到递归调用结束。
递归可以解决的问题一般有一下要求:
1需要求解的问题可以化为子问题求解,其子问题的求解方法与原问题相同,只是规模上的增加或减少。
2递归调用的次数是有限的,必须有结束条件。
但是我从网上有看到说非递归函数虽然效率高,但却比较难编程,而且相对来说可读性差。现代程序设计的目标主要是可读性好。随着计算机硬件性能的不断提高,程序在更多的场合优先考虑可读而不是高效,所以,鼓励用递归函数实现程序思想。
例如这个例题:
有3个方格,每个方格里面都有一个整数a1,a2,a3。已知0 <= a1, a2, a3 <= n,而且a1 + a2是2的倍数,a2 + a3是3的倍数, a1 + a2 + a3是5的倍数。你的任务是找到一组a1,a2,a3,使得a1 + a2 + a3最大。要求输入一个整数,输出最大值。
我用循环的答案:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,a=-1,p=0;
cin>>n;
for(int i=0;i<=n;++i)
for(int j=0;j<=n;++j)
{
if((i+j)%2==0)
for(int h=0;h<=n;++h)
if((j+h)%3==0)
if((i+j+h)%5==0)
{
if(a<i+j+h)
a=i+j+h;
}
}
cout<<a;
}
同学用递归的答案:
#include<bits/stdc++.h>
using namespace std;
int e[4],n,zong=0;
void fan(int,int,int,int);
int main()
{
int a,b,c;
cin>>n;
fan(0,0,0,1);
cout<<zong;
}
void fan(int x,int y,int z,int ji)
{
switch(ji)
{
case 1:for(int i=x;i<=n;i++)
{fan(i,y,z,2);}break;
case 2: for(int i=y;i<=n;i++)
{if((x+i)%2==0) fan(x,i,z,3);}break; case 3:for(int i=z;i<=n;i++)
{if((y+i)%3==0&&(x+y+i)%5==0&&(x+y+i)>=zong)
{zong=x+y+i;}
} } }
这个递归虽然看着比较麻烦,但是在思考上,我听同学的讲解还是更容易懂的。所以用好递归函数可以使自己的能力有一个较好的提升。