一、循环法:f1=1,f2=1,f3=f1+f2
int fab(int n)
{
if(n==1||n==2)
return 1;
int f1=1,f2=1;
int res=0;
for(int i=3;i<=n;i++)
{
res=f1+f2;
f2=f1;
f1=res;
}
return res;
}
二、递归法:F(n)=F(n-1)+F(n-2)可直接求出
类似分治法,都是将一个复杂的算法问题进行分解,让规模越来越小,使子问题容易求解
“”尾递归”就是函数或者子程序的最后一条语句为递归调用,因为每次调用后,再回到前一次调用的第一条语句,即return语句,所以不需要再进行任何运算工作了。
int fab(int n)
{
if (n < 2)
return n;
else
return (fab(n - 1) + fab(n - 2));
}
该递归算法调用本质上是二叉树形式,F(n-1),F(n-2)可以看作是F(n)的两个子树,而其自身又充当了一棵子树的树根,所以其算法的时间复杂度为O(2^n)。
三、动态规化法
上述递归法可以将复杂问题逐个拆分,但不能减少计算的时间,效率不高,而改用动态规划法,将以计算过的数据保存下来,就不必重复计算了,也不会继续往下递归,从而实现了提高性能的目的。
从上述执行的路径看,我们得知递归调用了9次,而执行加法运算4次,F(1)、F(0)共执行了3次,重复计算影响了性能,根据动态规划思想可修改代码为:
int output[100] = { 0 }; //fibonacci的暂存区
int fab(int n)
{
int res;
res = output[n];
if (res == 0)
{
if (n < 2)
res = n;
else
res = fab(n - 2) + fab(n - 1);
output[n] = res;
}
return res;
}