斐波那契数列(递归+迭代)

简介: 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、3

什么是斐波那契数列


斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、3


通俗地来讲,斐波那契数列就是从第三位数字开始,每位的值是其前两位的和


递归写法


使用递归方法写十分简单

从第三位数字开始,每位的值是其前两位的和


f(0) = 1

f(1) = 1

f(n) = f(n-1)+f(n-2)(n>3)

代码如下:


long long feibonahi(int n)
{
  if (n <= 2)
  {
  return 1;
  }
  else
  {
  return feibonahi(n - 1) + feibonahi(n - 2);
  }
}


使用递归写法的缺点

我们分析一下递归算法的时间复杂度





20c1e7ed414f40ae8a4c212757adaac5.png



可以看出这个递归方法的时间复杂度是O(2^n)


可能这是没觉得时间复杂度是O(2^n)是多大的事,所以接下来我们计算一下传不同参数,这个递归算法的运行时间:


#include <stdio.h>
#include <time.h>
long long Fib(int n)
{
  if (n <= 2)
  {
  return 1;
  }
  else
  {
  return Fib(n - 1) + Fib(n - 2);
  }
}
int main()
{
  int begin1 = clock();
  Fib(10);
  int end1 = clock();
  int begin2 = clock();
  Fib(20);
  int end2 = clock();
  int begin3 = clock();
  Fib(30);
  int end3 = clock();
  int begin4 = clock();
  Fib(40);
  int end4 = clock();
  int begin5 = clock();
  Fib(50);
  int end5 = clock();
  printf("end1:%d\n", end1 - begin1);
  printf("end2:%d\n", end2 - begin2);
  printf("end3:%d\n", end2 - begin3);
  printf("end4:%d\n", end4 - begin4);
  printf("end5:%d\n", end5 - begin5);
  return 0;
}



下面我们可以看到:

从参数从10~40的运行时间还算快,然而将50传入函数中,可以看到,会运行一段时间




62fcea9752824b5991e29d8051f3a696.png


所以使用递归方法求斐波那契数列在理论上可行,但是在实际中是不可取的一个方法


另外,我们在这也看一下2^N的“威力”


N==10,2^N = 1024

N==20,2^N = 100万

N==30,2^N = 10亿

N==40,2^N = 1万亿

N==50,2^N = 很大很大的数

所以我们不能使用递归算法,接下来我们写一个迭代方法


迭代写法(效率高)

int feibonahi2(int n)
{
  if (n == 1 || n == 2)
  {
  return 1;
  }
  int a = 1;
  int b = 1;
  int c = 1;
  while (n > 2)
  {
  c = a + b;
  a = b;
  b = c;
  n--;
  }
  return c;
}



这个算法的时间复杂度是O(N),上面的递归写法要好的太多太多


目录
相关文章
|
Ubuntu Linux 网络安全
使用Kali Linux虚拟机破解WiFi密码的一波三折及详细操作步骤
使用Kali Linux虚拟机破解WiFi密码的一波三折及详细操作步骤
4144 0
使用Kali Linux虚拟机破解WiFi密码的一波三折及详细操作步骤
|
5月前
|
存储 监控 前端开发
如何开发项目管理系统中的合同管理板块?(附架构图+流程图+代码参考)
合同管理是项目管理系统中的核心模块,涵盖合同生命周期、审批流程、履行监控及变更处理。通过数字化、自动化手段,提升管理效率,降低风险,确保合规性。本文详解合同管理模块的设计与开发,包括功能实现、业务流程及技术应用,助力企业构建高效管理系统。
|
存储 算法
Leetcode第三题(无重复字符的最长子串)
这篇文章介绍了解决LeetCode第三题“无重复字符的最长子串”的算法,使用滑动窗口技术来找出给定字符串中最长的不含重复字符的子串,并提供了详细的代码实现和解释。
625 0
Leetcode第三题(无重复字符的最长子串)
|
8月前
|
人工智能 自然语言处理 测试技术
自然语言生成代码一键搞定!Codex CLI:OpenAI开源终端AI编程助手,代码重构+测试全自动
Codex CLI是OpenAI推出的轻量级AI编程智能体,基于自然语言指令帮助开发者高效生成代码、执行文件操作和进行版本控制,支持代码生成、重构、测试及数据库迁移等功能。
1793 0
自然语言生成代码一键搞定!Codex CLI:OpenAI开源终端AI编程助手,代码重构+测试全自动
|
芯片
利用两个IO口检测6个按键
【8月更文挑战第23天】在资源受限的情况下,可通过巧妙设计使用两个I/O口检测六个按键。硬件连接上,六个按键以不同组合方式连接至IO1和IO2:键1连IO1与地;键2连IO2与地;键3同时连IO1和IO2;键4经电阻接IO1并接地;键5同样处理但接IO2;键6则各自经电阻连接至IO1和IO2后接地。软件方面,设置两I/O为输入模式并启用上拉电阻,依据高低电平的不同组合判断具体按键。此法需注意实际应用中的参数选择与优化。
526 2
|
C++
QT第一个程序命名空间详解,解释ui_widget的和xxx.cpp的联系
QT第一个程序命名空间详解,解释ui_widget的和xxx.cpp的联系
509 0
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
601 2
|
算法 搜索推荐 Java
【经典算法】LeetCode 215. 数组中的第K个最大元素(Java/C/Python3实现含注释说明,Medium)
【经典算法】LeetCode 215. 数组中的第K个最大元素(Java/C/Python3实现含注释说明,Medium)
535 3
|
算法 Java
快慢指针该如何操作?本文带你认识快慢指针常见的三种用法及在链表中的实战
快慢指针该如何操作?本文带你认识快慢指针常见的三种用法及在链表中的实战
559 0