递归
递归是数据结构中比较经典和不太好理解掌握的算法(我个人这么觉得,小声哔哔)
就字面意思而言,递归就是先递后归,其实就是先找到an和an-1的关系,然后用f(an) = g(an)*f(an-1)来替代f(an)。
话不多说,我们先上一个阿克曼函数的代码瞧瞧
#include<iostream>
using namespace std;
int ack(int m,int n)
{
if(m == 0) return n+1;
else if(n == 0) return ack(m-1,1);
else return ack(m-1,ack(m,n-1));
}
int main()
{
int n,m;
cin >> n >> m;
int ans = ack(m,n);
cout << ans << endl;
}
对应这个函数,我们来分析如何快乐地构造递归。
快乐的构造递归
- 首先,我们先找到递归的出口,即递归退出的条件。
- 找到f(an)和f(an-1)之间与n构成的关系
- 成功构造好了递归
递归构造进行时
对比构造方法,完成以下函数编写
1.斐波那契函数
#include<iostream>
using namespace std;
/***
其实在这我思考到一个问题,如果是多次查询,这样会重复计算许多次递归。
时间复杂度和空间复杂度都较高,可能会卡。
我们不妨对于类似这种数据多次使用,我们可以打个表记录下来。
(思路来源于素数表,哈哈)
***/
#define ll long long
ll F(int n)
{
if(n <= 1) return 1;
else return F(n-1)+F(n-2);
}
int main()
{
int n;
cin >> n;
ll ans = F(n);
cout << ans << endl;
}
2.gcd函数
#include<iostream>
using namespace std;
int gcd(int a,int b)
{
if(b == 0) return a;
else return gcd(a,a%b);
}
int main()
{
int a,b;
cin >> a >> b;
int ans = gcd(a,b);
cout << ans << endl;
}
/***
这个函数,其使用的时候经常出现的a,b都是long long 型的
***/
3.阶乘
#include<iostream>
using namespace std;
#define ll long long
ll f(int n)
{
if(n <= 1) return 1;
else return n*f(n-1);
}
int main()
{
int n;
cin >> n;
ll ans = f(n);
cout << ans << endl;
}
总结:遇见递归,放心大胆,按照递归函数的构造方法来构造递归函数。
就让我们一起快乐地上分吧。