斐波那契数列
//有一对兔子从出生到第三个月都开始生一对兔子,小兔子每月都会生一对兔子,假设在出生不死。
//第几月有多少对兔子
//斐波那契数列 1,1,2,3,5,8,13,21
//从每个数字是前两项的和
时间复杂度:时间复杂度实际就是一个函数,该函数计算的是执行基本操作的次数。
时间复杂度的O渐进表示:算法语句总的执行次数是关于问题规模N的某个函数,记为f(N),
N称为问题的规模。语句总的执行次数记为T(N),当N不断变化时,算法执行次数T(N)的
增长速率和f(N)的增长速率相同。则有T(N) =O(f(N)),称O(f(N))为时间复杂度的O渐进表示法。
空间复杂度:类似于算法的时间复杂度,它是算法所需存储空间的度量,记作S(n)=O(f(n))。
第一种 递推 (遍历)时间复杂度O(n)
#include<stdio.h>
int main(void)
{
int a1=1,a2=1,i;
for(i=0;i<10;i++)
{
printf("%d\t%d\t",a1,a2);
a1=a1+a2;
a2=a1+a2;
}
}
第二种 递归 时间复杂度O(2^n)
#include<stdio.h>
int fibonacci(int n){
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return fibonacci(n-1)+fibonacci(n-2);
}
int main(void)
{
int k,i=1;
scanf("%d",&k);
for(i=1;i<=k;i++)
{
printf("%d\t",fibonacci(i));
}
}
第三种 尾递归
2、尾递归
顾名思义,尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说,
函数调用出现在调用者函数的尾部, 因为是尾部, 所以根本没有必要去保存任何局部
变量. 直接让被调用的函数返回时越过调用者, 返回到调用者的调用者去。尾递归就
是把当前的运算结果(或路径)放在参数里传给下层函数,深层函数所面对的不是
越来越简单的问题,而是越来越复杂的问题,因为参数里带有前面若干步的运算路径。
尾递归是极其重要的,不用尾递归,函数的堆栈耗用难以估量,需要保存很多中
间函数的堆栈。比如f(n, sum) = f(n-1) + value(n) + sum; 会保存n个函数调用堆栈,
而使用尾递归f(n, sum) = f(n-1, sum+value(n)); 这样则只保留后一个函数堆栈即可,
之前的可优化删去。
#include<stdio.h>
#include<stdlib.h>
long Fib(long first, long second, long N)
{
if (N < 3)
return 1;
if (3 == N)
return first + second;
return Fib(second, first + second, N - 1);
}
int main()
{
int i,n = 0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("%d\t",Fib(1,1,i));
}
}