【C++】 斐波那契数列

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:

       F(0)=0,(n = 0)

       F(1)=1,(n = 1)

       F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)


斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368

特别指出:第0项是0,第1项是第一个1。

这个数列从第2项开始,每一项都等于前两项之和。

现实生活中,运用斐波那契数列的例子很多,而且这也是面试中经常会考到的经典问题

那么,这么一个看似不好想象的规律用代码怎么实现呢?


这里有几种方法:

  1. 递归实现:
    <时间复杂度O(2^N)>

#include <iostream>
using namespace std;

long long Fibonacci1(long long n) //用long long类型考虑到大数问题
{
   if (n < 2)
   {
     return n;
   }
   else
   {    
     return FIB(n-1) + FIB(n-2);
   }
}

int main()
{
   cout << Fibonacci1(5) << endl; // 求某一项的值    
   system("pause");
   return 0;
}

递归似乎看起来很简单明了,若给的项数n较大时,其效率较低。


2.非递归实现:

<时间复杂度O(N)>

long long Fibonacci2(int n)
{
   long long * fibArray = new long long[n+1];// 根据项数n开辟数组
   fibArray[0] = 0;
   fibArray[1] = 1; // 手动设置好前两个数,由此可以求得下一个数的值

    for(int i = 2; i <= n ; ++i)
   {
      fibArray[i] = fibArray[i-1] + fibArray[i-2]; // 当前数等于前两个数加和
   }

   long long ret = fibArray[n];
    delete[] fibArray ;

   return ret ;
}

非递归效率相对递归较高,但是两者意义相同。

这两种方法,都需要掌握。

下面将两种方法整合一起:

#include <iostream>
using namespace std;

long long fibonacci_1(int n)//递归
{
    if (n<2)
    {
        return n;
    }
    return fibonacci_1(n - 1) + fibonacci_1(n - 2);
}

void fibonacci_2(int n)//非递归
{
    int i;
    long long *fibArray = new long long[n + 1];
    fibArray[0] = 0;
    fibArray[1] = 1;
    for (i = 2; i<n; i++)
        fibArray[i] = fibArray[i - 1] + fibArray[i - 2];
    for (i = 0; i<n; i++)
        cout << fibArray[i] << " ";
}

int main(void)
{
    int i, n, k;
    printf("请输入斐波那契数列项数 :");
    cin >>n;
    printf("请选择:1.递归   2.非递归 :");
    cin >> k;
    if (k == 1)
    for (i = 0; i<n; i++)
        cout << fibonacci_1(i) <<" ";
    else
        fibonacci_2(n);

    system("pause");
    return 0;
}

若有纰漏,欢迎指正。


本文出自 “Vs吕小布” 博客,请务必保留此出处http://survive.blog.51cto.com/10728490/1761712

<think>我们被要求提供C++实现斐波那契数列的示例代码。根据引用,有递归和迭代(循环)两种主要方法。引用[1]和[2]展示了递归方法,但递归在n较大时效率低下(数级时间复杂度)。引用[3]和[4]展示了迭代方法,迭代方法具有线性时间复杂度,效率更高。我们将提供两种方法的代码示例,并比较它们的优缺点。斐波那契数列定义:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2)(n>=2)注意:有些实现从0开始(F0=0,F1=1),有些从1开始(F1=1,F2=1)。我们这里采用从0开始:即第0项为0,第1项为1。1.递归实现(简单但效率低,适合小规模n)2.迭代实现(效率高,适合大规模n)同时,我们也要注意引用[4]中的迭代实现与引用[3]略有不同(引用[4]使用了不同的迭代方式,每次计算两项,但本质上都是迭代)。我们将按照常见的迭代方式(引用[3]的方式)来实现,因为更直观。另外,引用[4]的代码中,函数fibonacci_circulate的实现是针对从1开始的斐波那契数列(即第1项和第2项都是1),而且它返回第n项(n从1开始计数)。但为了统一,我们按照从0开始(第0项为0)来实现。我们提供两个函数:-递归函数:fib_recursive-迭代函数:fib_iterative并在main函数中让用户输入n,然后分别用两种方法计算并输出结果(注意:当n较大时,递归方法会很慢甚至栈溢出,所以我们会提醒用户递归方法适用于小n)。同时,我们也会考虑边界情况(n为负数的情况,我们这里假设n>=0)。代码结构:#include<iostream>usingnamespacestd;//递归实现longlongfib_recursive(intn){if(n<=0)return0;if(n==1)return1;returnfib_recursive(n-1)+fib_recursive(n-2);}//迭代实现longlongfib_iterative(intn){if(n<=0)return0;if(n==1)return1;longlonga=0,b=1;longlongresult;for(inti=2;i<=n;i++){result=a+b;a=b;b=result;}returnresult;}intmain(){intn;cout<<"请输入一个非负整数n:";cin>>n;if(n<0){cout<<"输入错误,请输入非负整数!"<<endl;return1;}//递归方法计算(注意:当n较大时,递归会很慢,所以这里我们限制n的大小,比如只对n<=40使用递归)cout<<"递归方法计算:";if(n>40){cout<<"n值较大,递归方法可能较慢,这里跳过递归计算。"<<endl;}else{cout<<"F("<<n<<")="<<fib_recursive(n)<<endl;}cout<<"迭代方法计算:";cout<<"F("<<n<<")="<<fib_iterative(n)<<endl;return0;}注意:我们使用longlong类型,因为斐波那契数列增长很快,避免整数溢出。但是,引用[4]中使用了另一种迭代方式,它每次计算两项,然后根据n的奇偶性返回。我们这里不采用那种方式,因为直接迭代更清晰。另外,我们可以在迭代方法中避免使用额外的result变量,但为了清晰,我们保留。我们也可以考虑动态规划(但迭代方法本质就是动态规划的空间优化版本)。根据用户要求,我们提供代码示例,并且生成相关问题。注意:在main函数中,我们对于较大的n(>40)跳过了递归计算,因为递归计算大n会非常慢。下面我们按照格式要求输出代码。</think>### C++ 实现斐波那契数列示例代码 斐波那契数列的定义为:$F(0) = 0, F(1) = 1$,且当 $n \geq 2$ 时满足递推关系 $F(n) = F(n-1) + F(n-2)$。以下是两种高效实现方式: #### 1. 迭代法(推荐) 时间复杂度 $O(n)$,空间复杂度 $O(1)$,适合计算大数值项: ```cpp #include <iostream> using namespace std; long long fibonacci(int n) { if (n <= 0) return 0; if (n == 1) return 1; long long a = 0, b = 1, result; for (int i = 2; i <= n; ++i) { result = a + b; // F(n)=F(n-1)+F(n-2) a = b; // 更新前两项值 b = result; } return result; } int main() { int n; cout << "请输入项数 n: "; cin >> n; cout << "F(" << n << ") = " << fibonacci(n) << endl; return 0; } ``` #### 2. 递归法(仅教学演示) 时间复杂度 $O(2^n)$,空间复杂度 $O(n)$,仅适用于小数值项: ```cpp #include <iostream> using namespace std; long long fibonacci(int n) { if (n <= 0) return 0; if (n == 1) return 1; return fibonacci(n-1) + fibonacci(n-2); } // 主函数同上 ``` ### 关键说明 1. **迭代法优势**: - 避免递归的数级时间开销 - 支持计算 $n > 40$ 的项(递归法在 $n>40$ 时显著变慢) - 使用 `long long` 防止整数溢出($F(50) > 10^{10}$) 2. **注意事项**: - 当 $n > 93$ 时结果会溢出 `long long` 范围(最大值约 $9 \times 10^{18}$) - 输入负数时返回 0(根据数学定义 $F(n)=0$ 当 $n<0$) ### 性能对比 | 方法 | 计算 $F(40)$ 时间 | 最大可行 $n$ | |--------|-------------------|--------------| | 迭代法 | $\sim 1\mu s$ | $n \leq 93$ | | 递归法 | $\sim 1s$ | $n \leq 40$ | > 迭代法比递归法效率高百万倍以上[^3],实际应用务必使用迭代法[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值