递归算法/斐波那契数列

目录

递归

直接递归

间接递归

思想沿用

斐波那契数列


图片来源网络,侵权联系可删

递归

递归(Recursion)是一种编程技术,其中函数或方法直接或间接地调用自身。递归通常用于解决可以分解为更小、更简单的子问题的问题。递归的基本思想是将大问题分解为小问题,然后解决小问题,最后通过组合小问题的解来得到大问题的解。

递归有两种主要的形式:直接递归和间接递归。

直接递归

  1. 直接递归:函数直接调用自身。
/*** 计算阶乘*/
public class Factorial {/*** 递归实现阶乘** @param n* @return*/public static int factorial(int n) {if (n == 0) {return 1;} else {return n * factorial(n - 1);}}/*** 普通实现** @param n* @return*/public static int factorialTwo(int n) {if (n == 0) {return 1;}int ret = 1;for (int j = n; j >= 1; j--) {ret *= j;}return ret;}public static void main(String[] args) {System.out.println(factorial(5));  // 输出: 120System.out.println(factorialTwo(5));  // 输出: 120}
}

间接递归

public class IndirectRecursionFactorial {// 主函数,用于计算阶乘  public static long factorial(int n) {  if (n < 0) {  throw new IllegalArgumentException("Factorial is not defined for negative numbers.");  } else if (n == 0 || n == 1) {  return 1;  } else {  // 调用辅助函数来计算阶乘  return factorialHelper(n, 1);  }  }  // 辅助函数,用于递归计算阶乘  private static long factorialHelper(int n, long result) {  if (n == 1) {  return result;  } else {  // 递归调用自身,将n减1,并将当前数与之前的结果相乘  return factorialHelper(n - 1, n * result);  }  }  public static void main(String[] args) {  // 测试代码,计算5的阶乘  long factorialOf5 = factorial(5);  System.out.println(factorialOf5);  }  
}

注:间接递归更是可以作为记忆化(也称为动态规划)来更优秀的实现很多,在辅助函数中处理记录已经计算过的数值,用于下次递归不需要再进行代码逻辑处理

思想沿用

有没有发现很多算法思想都是沿用的递归。递归思想的核心是将一个大问题或复杂任务分解为若干个小问题或子任务,然后逐个解决这些小问题或子任务,最终将它们的解决方案组合起来,得到原问题的解。这种分解和组合的过程通常通过函数或方法自身的调用来实现,即方法或函数直接或间接地调用自身。递归思想在很多算法和数据结构中都有应用,例如树的遍历、图的搜索等。

  1. 排序和搜索算法:递归常用于实现排序和搜索算法。例如,快速排序和归并排序都是基于递归的排序算法。它们通过将问题分解为更小的问题来排序数据,然后再将结果合并起来。此外,二分搜索也使用了递归思想。

  2. 树的遍历:在数据结构如树和图的遍历中,递归是一种非常自然和有效的解决方案。例如,二叉树的前序、中序和后序遍历,以及图的深度优先搜索(DFS)和广度优先搜索(BFS,尽管BFS通常使用队列实现而非递归)都可以使用递归来实现。

  3. 分治算法:分治算法是一种典型的递归思想的应用,它将一个大问题划分为若干个相对独立的子问题,递归地解决这些子问题,然后将子问题的解合并起来,得到原问题的解。除了快速排序和归并排序,其他如棋盘覆盖问题、旅行商问题等也可以通过分治算法和递归来解决。

  4. 动态规划:动态规划问题通常也可以使用递归来表达其状态转移方程。然而,为了避免重复计算,通常会结合记忆化搜索或迭代的方式来优化递归解法。递归为动态规划提供了一种自然的建模方式。

  5. 数学归纳法:递归与数学归纳法的思想密切相关。当问题的解决方案基于其更小规模的情况时,递归是一种自然的选择。例如,斐波那契数列和阶乘问题都可以通过数学归纳法建模,并用递归解决。

  6. 游戏开发和计算机图形学:在游戏开发和计算机图形学领域,递归也常用于解决一些复杂的路径查找和图形渲染问题。例如,迷宫寻路算法就经常采用递归实现。

  7. 表达式求值:在编译器和解释器设计中,递归常用于解析和求值复杂的数学表达式或编程语言的语法结构。

注:虽然递归思想在许多情况下都很有用,但它也可能导致性能问题,特别是当递归深度很大时,可能会导致栈溢出。

斐波那契数列

既然说到了递归,必然想到了斐波那契数列,斐波那契数列是一个经典的递归问题,其定义本身就是递归的:每个数字是前两个数字的和。

斐波那契数列是这样定义的:

F(0) = 0
F(1) = 1
F(n) = F(n-1) + F(n-2),对于所有n > 1

这个定义中的 F(n) = F(n-1) + F(n-2) 是一个递归公式,它表示第 n 个斐波那契数是通过前两个斐波那契数计算得到的。这种自我引用的特性正是递归的核心。

使用递归方法来实现斐波那契数列是非常直观的。

/*** 斐波那契* 斐波那契数列(Fibonacci sequence),又称黄金分割数列,是由意大利数学家列昂纳多·斐波那契提出的。* 这个数列从第三项开始,每一项都等于前两项之和。具体数值为: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*)。* 这意味着第三项是前两项的和,第四项是第三项和第二项的和,以此类推。*/
public class MutualRecursion {public static int fibonacciA(int n) {  if (n <= 1) {  return n; // 基本情况,终止条件  } else {  return fibonacciB(n - 1) + fibonacciB(n - 2); // 调用funcB  }  }  public static int fibonacciB(int n) {  if (n <= 1) {  return n; // 基本情况,终止条件  } else {  return fibonacciA(n - 1) + fibonacciA(n - 2); // 调用funcA  }  }  public static void main(String[] args) {  System.out.println(fibonacciA(8)); // 输出斐波那契数列的第5项}  

 

这种直接的递归实现方式在计算较大的斐波那契数时效率非常低,因为它会重复计算很多相同的子问题。例如,为了计算 F(5),它会计算 F(4) 和 F(3),而计算 F(4) 时又会计算 F(3) 和 F(2),这样就重复计算了 F(3)。这种重复计算随着 n 的增大而急剧增加,导致算法的时间复杂度呈指数级增长。

为了提高效率,我们可以使用记忆化(也称为动态规划)或迭代方法来避免重复计算。记忆化是通过将已经计算过的子问题的结果存储起来,在需要时直接查找而不是重新计算。迭代方法则是通过循环来逐步计算斐波那契数列的每一项,而不是使用递归调用。

总之,递归是计算斐波那契数列的一种直观方法,但需要注意其效率问题。在实际应用中,我们通常会选择更高效的算法来计算斐波那契数列。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/3355.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文速览Llama 3及其微调:如何通过paper-review数据集微调Llama3 8B

前言 4.19日凌晨正准备睡觉时&#xff0c;突然审稿项目组的文弱同学说&#xff1a;Meta发布Llama 3系列大语言模型了 一查&#xff0c;还真是 本文以大模型开发者的视角&#xff0c;基于Meta官方博客的介绍&#xff1a;Introducing Meta Llama 3: The most capable openly a…

linux 系统文件目录颜色及特殊权限对应的颜色

什么决定文件目录的颜色和背景&#xff1f; 颜色 说明 栗子 权限白色表示普通文件 蓝色表示目录 绿色表示可执行文件 浅蓝色链接文件 黄色表示设备文件 红色 表示压缩文件 红色闪烁表示链接的文件有问题 灰色 表示其它文件 可以用字符表示文件的类型&am…

Netty快速入门

网络通信模型 在了解Netty之前&#xff0c;我们可以简单的先了解一下我们的网络通信方式&#xff0c;正所谓知其然&#xff0c;知其所以然。只有了解了网络通信模型&#xff0c;我们才能更好的去理解Netty的一些核心的原理。 如下图是一个简单的请求发送的时候的一个大概的HTT…

【Linux】GDB调试器学起来!指令全解,建议收藏

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

面试十五 容器

一、vector容器 template<typename T> class Allocator{ public:T* allocator(size_t size){// 负责内存开辟return (T*)malloc(sizeof(T) * size);}void deallocate(void * p){free(p);}void construct(T*p,const T&val){// 定位newnew (p) T(val);}void destroy(…

访问控制列表配置实验

ACL&#xff0c;全称 Access Control List&#xff08;访问控制列表&#xff09;&#xff0c;是一种实现访问控制的机制&#xff0c;用于规定哪些主体&#xff08;如用户、设备、IP地址、进程等&#xff09;可以对哪些资源&#xff08;如网络服务、文件、系统对象等&#xff09…

2024深圳杯C题的8页思路分析+所有代码可执行+参考文献+持续更新参考论文(已经更新了代码与图像)

比赛题目的完整版思路可执行代码数据参考论文都会在第一时间更新上传的&#xff0c;大家可以参考我往期的资料&#xff0c;所有的资料数据以及到最后更新的参考论文都是一次付费后续免费的。注意&#xff1a;&#xff08;建议先下单占坑&#xff0c;因为随着后续我们更新资料数…

docker入门学习

一、docker概念 Docker 引擎是使用的是Linux内核特性的容器引擎。 二、docker的安装 1.docker&#xff0c;下载地址&#xff1a; 桌面版&#xff1a;Docker Desktop: The #1 Containerization Tool for Developers | Docker 服务器版&#xff1a;Install Docker Engine | D…

# 从浅入深 学习 SpringCloud 微服务架构(六)Feign(3)

从浅入深 学习 SpringCloud 微服务架构&#xff08;六&#xff09;Feign&#xff08;3&#xff09; 一、组件的使用方式总结 1、注册中心 1&#xff09; Eureka 搭建注册中心 引入依赖 spring-cloud-starter-netflix-eureka-server。 配置 EurekaServer。 通过 EnableEure…

前端路由的实现原理

当谈到前端路由时&#xff0c;指的是在前端应用中管理页面导航和URL的机制。前端路由使得单页应用&#xff08;Single-Page Application&#xff0c;SPA&#xff09;能够在用户与应用交互时动态地加载不同的视图&#xff0c;而无需每次都重新加载整个页面。 在前端开发中&…

如何在阿里云快速配置自动定时重启ECS云服务器?

背景 无论是电子商务、在线教育、游戏&#xff0c;还是流媒体等业务&#xff0c;服务器的稳定运行都是至关重要的。然而&#xff0c;在实际运行中&#xff0c;我们可能会遇到这样一些场景&#xff1a; 系统更新&#xff1a;一些操作系统或者软件的更新可能需要重启服务器才能…

bit、进制、位、时钟(窗口)、OSI七层网络模型、协议、各种码

1.bit与进制 &#xff08;个人理解&#xff0c;具体电路是非常复杂的&#xff09; 物理层数据流&#xff0c;bit表示物理层数据传输单位&#xff0c; 一个电路当中&#xff0c;通过通断来表示数字1和0 两个电路要通讯&#xff0c;至少要两根线&#xff0c;一根作为电势参照…

Java中使用Graphics2D绘制字符串文本自动换行 算法

效果&#xff1a; 代码&#xff1a; /*** return void* Author xia* Description //TODO 写字换行算法* Date 18:08 2021/4/1* Param []**/private static void drawWordAndLineFeed(Graphics2D g2d, Font font, String words, int wordsX, int wordsY, int wordsWidth) {FontD…

东北大学工程训练CNC加工中心(坤图)

东北大学加工中心&#xff08;CNC&#xff09;采用的系统为FANUC系统。 要求学生自主设计图样&#xff0c;编写GCODE文件&#xff0c;操作电脑使机床按设计路径铣出图案。 本人设计的图样为坤坤图 图为用CAD设计绘制的图样。 计算坐标&#xff0c;设计铣刀轨迹&#xff0c;得…

Linux--基础IO(上)

目录 1. 文件的边角知识 1.1 文件是什么&#xff1f; 1.2 文件是怎么打开的&#xff1f; 1.3 进程与文件 进程与文件的关系 2. 重温c语言文件接口 2.1 打开文件的方式 2.2 读写文件接口的重温 2.2.1 写文件 2.2.2 读文件 3. 系统文件I/O 3.1 系统接口 3.2 系…

【深度学习-第5篇】使用Python快速实现CNN分类(模式识别)任务,含一维、二维、三维数据演示案例(使用pytorch框架)

在之前的文章中介绍了CNN的图解入门&#xff0c;CNN的MATLAB分类实现&#xff0c;CNN的MATLAB回归实现。 卷积神经网络(Convolutional Neural Networ&#xff0c;简称CNN)是一种广泛应用于图像识别领域的深度学习算法。它通过模拟人类视觉系统的层次结构&#xff0c;可以自动提…

nginx-1.24.0 安装教程

下载nginx安装包 mkdir -p /home/app cd /home/app wget http://nginx.org/download/nginx-1.24.0.tar.gz 解压缩 tar -zxf nginx-1.24.0.tar.gz 下载nginx二进制包编译所需的工具和依赖 yum install gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel -y 编译…

Arduino平衡小车

一&#xff0c;TB6612FNG电机驱动芯片 TB6612FNG是东芝半导体公司生产的一款直流电机驱动器件&#xff0c;它具有大电流MOSFET-H桥结构&#xff0c;双通道电路输出&#xff0c;可同时驱动2个电机. 参数名称参数值电压范围2.7-5.5V最大输入电压15V输出电流1.2A(平均)/3.2A&…

Vitis HLS 学习笔记--HLS入门示例集合-目录

目录 1. 示例集合概述 2. Interface 接口 2.1 Aggregation_Disaggregation 聚合与解聚 2.1.1 aggregation_of_m_axi_ports 2.1.2 aggregation_of_nested_structs 2.1.3 aggregation_of_struct 2.1.4 auto_disaggregation_of_struct 2.1.5 disaggregation_of_axis_port …

模块化 手写实现webpack

模块化 common.js 的导入导出方法&#xff1a; require \ export 和 module.exports export 和 module.export nodejs 内存1.4G -> 2.8G cjs ESModule 主要区别&#xff1a; require属于动态类型&#xff1a;加载执行 同步 esmodul是静态类型&#xff1a;引入时并不会真的去…