写一个函数,输入n,求斐波那契数列(Fibonacci)的第n项。
延申题目:青蛙跳台阶的问题:一只青蛙一次跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级的太极总共有多少种跳法。
当有0阶台阶时,有0种跳法。
1 ******************************** 1
2 ******************************** 2
当n大于2时,第一次跳有两种跳法,1、跳一阶。此时的跳法数目为后面的n-1阶跳法数目。2、跳两阶,此时的跳法数目为n-2阶跳法数目。所以总的跳法数目为f(n-1) + f(n-2)。
3 ******************************** 3
4 ******************************** 6
n ******************************** f(n-1) + f(n-2)
实际上也是一种斐波那契数列,只是f(2)不一样。
第一种:
#include "../common.h"
u_int64_t fibonacci(u_int32_t n)
{
if(n <= 1)
{
return n;
}
else
{
return fibonacci(n-1) + fibonacci(n-2);
}
}
int main()
{
clock_t startTime,endTime;
int n;
printf("please input n = ");
scanf("%d",&n);
getchar();
startTime = clock();
u_int64_t data = fibonacci(n);
printf("fibonacci(%u) = %lu\n",n,data);
endTime = clock();
printf("run time:%f\n",double(endTime - startTime)/CLOCKS_PER_SEC);
}
这种采用递归的方式,时间效率极低:
当输入的n较大时(eg:100),需要花费很长的时间。
第二种:
#include "../common.h"
u_int64_t fibonacci(u_int32_t n)
{
if(n <= 1)
{
return n;
}
u_int64_t fibOne = 0;
u_int64_t fibTwo = 1;
u_int64_t fibN = 0;
for(u_int32_t i = 2; i <= n; ++i)
{
fibN = fibOne + fibTwo;
fibOne = fibTwo;
fibTwo = fibN;
}
return fibN;
}
int main()
{
clock_t startTime,endTime;
int n;
printf("please input n = ");
scanf("%d",&n);
getchar();
startTime = clock();
u_int64_t data = fibonacci(n);
printf("fibonacci(%u) = %lu\n",n,data);
endTime = clock();
printf("run time:%f\n",double(endTime - startTime)/CLOCKS_PER_SEC);
}
这种实现方式时间复杂度为:O(n)。
结果对比:
bekl@bekl:~/test2021/斐波那契数列$ ./2
please input n = 30
fibonacci(30) = 832040
run time:0.000085
bekl@bekl:~/test2021/斐波那契数列$ ./1
please input n = 30
fibonacci(30) = 832040
run time:0.005523