对于很多编程初学者来说,递归算法是学习语言的最大障碍之一。很多人也是半懂不懂,结果学到很深的境地也会因为自己基础不好,导致发展太慢。

可能也有一大部分人知道递归,也能看的懂递归,但在实际做题过程中,却不知道怎么使用。今天,我们就来说一说递归算法的使用。

什么是递归

递归,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。也就是说,递归算法是一种直接或者间接调用自身函数或者方法的算法。

通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解。

递归的基本原理

第一:每一级的函数调用都有自己的变量。

第二:每一次函数调用都会有一次返回。

第三:递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序。

第四:递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反。

第五:虽然每一级递归都有自己的变量,但是函数代码并不会得到复制。

递归的优缺点

优点

缺点

●实现简单

●可读性好

●递归调用,占用空间大

●递归太深,易发生栈溢出

●可能存在重复计算

递归的三大要素

第一要素:明确你这个函数想要干什么。先不管函数里面的代码什么,而是要先明白,你这个函数的功能是什么,要完成什么样的一件事。

第二要素:寻找递归结束条件。我们需要找出当参数为啥时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么。

第三要素:找出函数的等价关系式。我们要不断缩小参数的范围,缩小之后,我们可以通过一些辅助的变量或者操作,使原函数的结果不变。

递归的过程

具体地说,如果递归函数调用自己,则被调用的函数也将调用自己,这将无限循环下去,除非代码中包含终止调用链的内容。通常的方法将递归调用放在if语句中。例如,void类型的递归函数recurs()的代码如下:

用文字再现这段代码块的内容:

只要if语句为true,每个recurs()调用都将执行statement1,然后再调用recurs(),而不会执行statements2 。当前调用结束后,程序控制权将返回给调用它的recurs(),而该recurs()将执行其statements2部分,然后结束,并将控制权返回给前一个调用,依次类推。

递归的使用

递归的强大之处在于它允许用户用有限的语句描述无限的对象。因此,在计算机科学中,递归可以被用来描述无限步的运算,尽管描述运算的程序是有限的。 这一点是循环不太容易做到的。

编写正确的递归算法,一定要有 ”归“ 的步骤,也就是说递归算法,在分解问题到不能再分解的步骤时,要让递归有退出的条件,否则就会陷入死循环,最终导致内存不足引发栈溢出异常。

下面,我们通过两个例子来学习一下,递归的使用:

例一:递归求阶乘

例二:递归求斐波那契数列

从上面的步骤我们可以清晰的看到递归算法的第一步是分治,把复杂的大的问题,给拆分成一个一个小问题,直到不能再拆解,通过退出条件retrun,然后再从最小的问题开始解决,只到所有的子问题解决完毕,那么最终的大问题就迎刃而解。

递归的优化方法

递归问题中想到思路本身不非常难,真正的难点在于如何优化。

1、考虑是否重复计算

如果你使用递归的时候不进行优化,是有非常非常非常多的子问题被重复计算的。因此,使用递归的时候,必要须要考虑有没有重复计算,如果重复计算了,一定要把计算过的状态保存起来。

2、考虑尾递归

对于递归的问题,我们一般都是从上往下递归的,直到递归到最底,再一层一层着把值返回。

不过,有时候当 n 比较大的时候,例如当 n = 10000 时,那么必须要往下递归10000层直到 n <=1 才将结果慢慢返回,如果n太大的话,可能栈空间会不够用。这个时候,就可以用尾递归优化来解决。

顾名思义,尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说, 函数调用出现在调用者函数的尾部, 因为是尾部, 所以根本没有必要去保存任何局部变量。直接让被调用的函数返回时越过调用者, 返回到调用者的调用者去。

有的人刚接触算法的时候,一直都惧怕递归,也很少或者说几乎就不写递归的代码。但其实学习了以后,发现递归还是挺可爱的。就像在数学找一组数字的规律一样,可以锻炼我们的思维。希望这篇文章,能额昂你有所收获。

相关链接:

几种快速优化MongoDB的方法,从此优化不再难!

4种网页设计技巧:图文搭配,网页不累!

巧用这10条MySQL技巧,事半功倍!

学会这8个Mybatis使用技巧,让你省去没必要的麻烦

点击文末“”咨询,免费来云和试听课程——UI视觉交互全科班、Python人工智能高薪班、JAVA大数据企业直通班、HTML5全栈精英班、Unity虚拟现实大师班,座位有限,先抢先得

可能存在无限递归_你为什么学不会递归?读完这篇文章轻松理解递归算法相关推荐

  1. 2.2基本算法之递归和自调用函数_你为什么学不会递归?读完这篇文章轻松理解递归算法...

    对于很多编程初学者来说,递归算法是学习语言的最大障碍之一.很多人也是半懂不懂,结果学到很深的境地也会因为自己基础不好,导致发展太慢. 可能也有一大部分人知道递归,也能看的懂递归,但在实际做题过程中,却 ...

  2. java break递归_【Java】递归总结

    摘要: 大师 L. Peter Deutsch 说过:To Iterate is Human, to Recurse, Divine.中文译为:人理解迭代,神理解递归.毋庸置疑地,递归确实是一个奇妙的 ...

  3. 组织架构递归_映射架构和递归管理数据–第2部分

    组织架构递归 介绍 (Introduction) In Part 1 of this article, we built a case for the benefits of documenting ...

  4. 组织架构递归_映射架构和递归管理数据–第1部分

    组织架构递归 介绍 (Introduction) In a typical OLTP environment, we want to maintain an acceptable level of d ...

  5. python 画树 递归_数据结构 - python如何递归生成树?

    问 题 class Tree: def __init__(self, label): self.root = label self.child = {} def set_child(self, lab ...

  6. 数组重复次数最多的元素递归_在不使用递归的情况下计算链接列表中元素的出现次数...

    数组重复次数最多的元素递归 Solution: 解: Input: 输入: A singly linked list whose address of the first node is stored ...

  7. java break递归_如何利用Java递归解决“九连环”公式

    在之前有写到过一点点有关递归的东西,然后想到小时候自己玩的一个玩具--九连环.小时候自己曾经一边玩一边用笔记下来解开这个东西的公式,那是十几年前的事情了.前两天突然想起来,九连环的基本操作就是一个递归 ...

  8. java整数划分递归_整数划分问题(递归法)

    整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都将涉及.所谓整数划分,是指把一个正整数n写成如下形式: n=m1+m2+...+mi; (其中mi为正整数,并且1 < ...

  9. java整数划分递归_整数划分(递归)

    整数划分问题是算法中一个经典命题之一,有关问题的讲述在讲解到递归时基本都会提到: 所谓整数划分:指把一个正整数n写成如下形式: n=m1+m2+........mi;(mi为正整数,并且1<=m ...

最新文章

  1. HDU2648(map的应用)
  2. linux下安装mysql5.7.25详细教程
  3. html元素li移动动态效果
  4. 线性代数思维导图_线性代数入门级思维导图
  5. unity, 非public变量需要加[SerializeField]才能序列化
  6. 简单递推公式转换矩阵求解
  7. 【经典回放】JavaScript学习详细干货笔记之(二)
  8. [Node.js] mySQL数据库 -- promise
  9. 腾讯否认微信测试语音消息进度调节​;监证会同意蚂蚁集团科创板IPO注册;React 17 正式版发布|极客头条
  10. js浮点数加减乘除精度不准确
  11. Linux版Flash亮相,但64位版需时间
  12. 软件测试职业发展三步曲之一
  13. java中什么是接口代码详解
  14. HTML初步认识和一些简单常用属性
  15. 工控通讯经历1:(C#)三菱FX5U-32M与上位机通讯(超详细!)
  16. 小说作者推荐: 闹月合集
  17. vivado使用tcl脚本一键生成mcs文件
  18. SAP系统资产年结步骤、以及资产年结错误后处理方式
  19. 谷歌地图 marker 更改经纬度
  20. 查询表结构sql语句

热门文章

  1. hadoop 2.5.0安装和配置
  2. 【Android开发】之Fragment与Acitvity通信
  3. 使用jq的toggle函数实现全选功能遇到的问题
  4. 面向对象并不是必要的
  5. 华为智能手环智能手表软件测试,一块智能手表的测试之旅,揭秘华为运动健康科学实验室...
  6. mysql 视图 分页_mysql查看所有存储过程,函数,视图,触发器,表,分页
  7. git回退历史版本无法上传_Git系列教程(二):版本库中添加文件、版本回退
  8. PLSQL Developer导入csv文件到oracle
  9. 当使用easyui时,表单的onchange事件失效
  10. linux 硬盘繁忙,icinga2 借助check_iostat.sh抓取linux服务器的diskIO(硬盘繁忙度)