用递归和非递归分别实现斐波那契数列

斐波那契数列介绍:斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
根据以上的递推公式,我们很容易可以得到递归的解决办法
实现代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int Fib(int n) {//用递归实现斐波那契数列
        int result;
        if (n == 1 || n == 2) {
                 return 1;
        }
        result = Fib(n - 1) + Fib(n - 2);
        return result;
}
int main() {
        int n;
        scanf("%d", &n);
        int ret=Fib (n);
        printf("ret=%d\n", Fib(n));
        system("pause");
        return 0;
}

由代码可以看出递归的办法非常简短,直接将斐波那契数列的递推公式带入即可实现,但与此同时这个办法也有一个缺点,那就是效率低下,当n较大时,计算斐波那契数需要很长时间,这是因为程序在每次递归调用自己时都需要算一遍n-1和n-2项,存在很多重复计算,我们可以使用代码来看一下,当计算n为40的斐波那契数时,要做多少次运算。(暂且不考虑溢出的情况)

int count = 0;
int Fib(int n) {//用递归实现斐波那契数列
 int result;
 if (n == 1 || n == 2) {
  return 1;
 }
 if (n == 3) {
  ++count;
 }
 result = Fib(n - 1) + Fib(n - 2);
 return result;
}

增加一个变量count,通过这个变量的值来看一下n为40时的运算次数
在这里插入图片描述
我们可以发现运算量实在太大了,那怎么解决这样的问题呢,我们可以使用非递归的办法来求斐波那契数列。
实现代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int Fib2(int n) {
        if (n == 1 || n == 2) {
                 return 1;
        }
        int last2 = 1;//第i-2项
        int last1 = 1;//第i-1项
        int result = 0;
        for (int i = 3; i <= n;++i) {      //每次循环都要更新前一项与前两项的值
                 result = last1 + last2;
                 last2 = last1; 
                 last1 = result;
        }
        return result;
}
int main() {
        int n;
        scanf("%d", &n);
        int ret=Fib(n);
        printf("ret=%d\n", Fib (n));
        system("pause");
        return 0;
}

前一个递归之所以效率低是因为重复计算的原因,那如果可以避免掉这样的重复计算,递归方法还是可以提高效率的。
实现代码:

#include<stdio.h>
#include<stdlib.h>
int Fib(int n, int last2, int last1) {
 if (n == 2|| n==1) {
  return last1;
 }
 return Fib(n - 1, last1, last1 + last2);
}
int main() {
 //int n;
 //scanf("%d", &n);
 int ret = Fib(9, 1, 1);
 printf("%d\n", ret);
 system("pause");
 return 0;
}

增加了函数参数,每次将计算结果存到last1中,最后返回last1的值,即可得到相应的斐波那契数。
n=9时的运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值