使用递归解决斐波那契数列的性能问题

我们知道斐波那契数列(也称作兔子数列)  1,1,2,3,5,8,13,21,34。。。。。

前两位数固定是1,之后每一位数都是前两位数的之和,这样的数列就是斐波那契数列

那么我们要求这样的数列,就必须要求n-1和n-2位数

    function getFB(n){
      if(n == 1 || n == 2){       // 这里我们先保持前两位数是1
        return 1;
      }else {
        return getFB(n-1) + getFB(n-2);
      }
    }
    console.log(getFB(10));

求斐波那契数列的第十位   在控制台中打印出来的是 55

那么  第五十位呢?。。。。。。。。。

很好,我的浏览器卡死崩溃了

由此我们可知,这样求斐波那契数列实在是太浪费性能了

既然有问题我们就来解决它

那么   求斐波那契数列的时候是为什么会浪费性能呢?

原因就是浏览器求了太多重复项

var i = 0; //声明一个变量,用来记录调用getFB()方法的次数
    function getFB(n){
      i++;
      if(n == 1 || n == 2){
        return 1;
      }else {
        return getFB(n-1) + getFB(n-2);
      }
    }
    console.log(getFB(20));// 我的浏览器求不出来这么多项 所以换了小一点的数字
    console.log(i);

求斐波那契数列的第20位会调用13529次函数

那么求第30位呢?

多达16万次

第40位呢?第50 位呢?。。。。。。。

所以这个样子实在是太浪费性能了

解决问题的思路:我们把已经求过的项用一个变量保存起来,如果下次还需要用到这个项就直接取出来用,而不是再去调用函数

 var i = 0;//声明一个变量i,记录调用getFB这个函数的次数.
    //声明一个对象obj,用来保存已经求过的项.
    var obj = {};
    function getFB(n){
      i++;
      //求n位是多少,就先去obj里面看看,之前求过没有,如果之前求过,就直接取出来使用.
      if(obj[n] != undefined){
        //如果进到了这里,说明当前这个n位已经求过,已经存进obj里面了
        return obj[n];
      }else {
        //如果进到这里来了,就说明当前这个n位之前没求过,没求过就求呗.
        if(n == 1 || n == 2){
          obj[n] = 1;
          return 1;
        }else {
          obj[n] = getFB(n-1) + getFB(n-2);
          return obj[n];
        }
      }
    }

    console.log(getFB(60));
    console.log(i);

那么我们就来看看结果吧

斐波那契数列的第60位大的吓人,但是我们却也只调用了117次函数,极大的提高了性能

原文地址:https://www.cnblogs.com/mlw1814011067/p/9439651.html

时间: 2024-10-14 04:13:20

使用递归解决斐波那契数列的性能问题的相关文章

使用递推和递归解决斐波那契数列问题~~~

/** * 使用递推的方式处理斐波那契数列 * @param sum * @param i * @return */ public static int findValue(int n){ if(n==1) { return 1; } if(n==2) { return 2; } int sum=1; int pre=1; for(int i=3;i<=n;i++) { int temp=sum; sum+=pre; pre=temp; } return sum; } /** * 采用递归的方式

13、蛤蟆的数据结构笔记之十三栈的应用之栈与递归之斐波那契数列

13.蛤蟆的数据结构笔记之十三栈的应用之栈与递归之斐波那契数列 本篇名言:"人生不是一支短短的蜡烛,而是一支由我们暂时拿着的火炬,我们一定要把它燃得." 继续递归的斐波那契数列问题. 欢迎转载,转载请标明出处: 1.  斐波那契数列 斐波那契数列,又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)在现代物理.准晶体结构.化学

249 递归:概念,利用递归求1~n的阶乘,利用递归求斐波那契数列,利用递归遍历数据

6.1什么是递归 递归:如果一个函数在内部可以调用其本身,那么这个函数就是递归函数. 简单理解: 函数内部自己调用自己, 这个函数就是递归函数 注意:递归函数的作用和循环效果一样,由于递归很容易发生"栈溢出"错误(stack overflow),所以必须要加退出条件return. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&g

递归与斐波那契数列

一.递归 在函数内部,可以调用其他函数;如果一个函数在内部调用自己,那这个函数就是递归函数. 案例:遍历当前目录下的所有文件 1.递归遍历 1 import os 2 def gci(filepath): 3 #遍历filepath下所有文件,包括子目录 4 files = os.listdir(filepath) 5 for fi in files: 6 fi_d = os.path.join(filepath,fi) 7 if os.path.isdir(fi_d): 8 gci(fi_d)

Python递归及斐波那契数列

递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * ... * n,用函数 fact(n)表示,可以看出:fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n所以,fact(n)可以表示为 n * fact(n-1),只有n=1时需要特殊处理.于是,fact(n)用递归的方式写出来就是: def fact(

递归之斐波那契数列

在数学上,費波那契數列是以递归的方法來定义: (n≧2) 用文字來说,就是斐波那契数列由0和1开始,之後的斐波那契数列就由之前的兩数相加. 这也是从维基百科上摘来的表述,比较的专业点.那个简单的写一下前面的几个是: 0,1,1,2,3,5,8,13,21,34,55,89,144,233...... 这个也是成一个指数增长的现象,所以兔子要是都按这个节奏生长,那就天天有肉吃了,还便宜!!! 这个问题相对与汉诺塔问题,较我而且,斐波那契数列一目了然,比较的好理解. 下面就用Ptyhon来实现一下:

关于递归和斐波那契数列

这次的题目是要求用递归算法求斐波那契数列的第n项. 众所周知:斐波那契数列中的项等于前两项相加的和,第一项为0,第二项为1.那么我们可以轻易得到递归公式: f(n)=f(n-1)+f(n-2); 其中,第一项为0,第二项为1: if(n==1) return 0; if(n==2) return 1; 然后得到如下代码: #include<stdio.h> int f(int n); int main() { int n; scanf("%d",&n); print

【递归】斐波那契数列第n个数

递归.递推计算斐波那契数列第n项的值: 1 #include <stdio.h> 2 long long fact(int n); //[递推]计算波那契数列第n个数 3 long long fact2(int n);//[递归] 4 int main(int argc, char *argv[]) 5 { 6 int i=1; 7 while(i<=10) 8 { 9 printf("%d %I64d %I64d\n",i,fact(i),fact2(i)); 10

递归求斐波那契数列

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Console.Write("输入想求的斐波那契数列项数:"); int n = Conver