对于递归的理解

0.写在前面

说明一下,本篇博客偏向于理论,一些例子例题看参考博客就好了。

1.简单理解递归

首先抛开你脑中对递归的想法,单纯先来看看这一个问题。

  • 汉诺塔问题
    汉诺塔问题描述的是:有三根柱子,在第一根柱子自下而上的按大小顺序添加圆盘,要求依次取出圆盘添加到另一根柱子上,但是要保持原有的结构,就是自下而上从大到小叠加,而且大圆盘不能放在比它小的圆盘上面,三根柱子之间一次只能移动一个圆盘。求将全部圆盘移动到另一根柱子需要移动几次?(参考资料中有图解版)。
    具体过程就不分析了,参考资料有。要想一下子解出n个圆盘需要移动几次,这恐怕很有难度。或许我们可以试着先解出3个圆盘需要移动几次。通过操作的过程,很容易发现了,3个圆盘移动的次数是在移动了2个圆盘的次数上加上移动最后一个大圆盘。经过一些列操作可以发现,
    移动n个圆盘次数=移动n-1个圆盘次数+移动第n个圆盘次数
  • 谈谈递归
    什么是递归:简单来说,在程序中就是方法调用方法本身。但是严格来说,递归其实是一种体现在算法中的思想。汉诺塔问题很显然就可以使用递归的算法去解决。在解决问题时,可以将一个复杂的问题分解成多个同样的子类问题(个人理解是逐层分解),然后解决某一层的问题时可以用前一层的结果。“将一个复杂的问题分解成多个同样的子类问题”可以理解为“递去”,“解决某一层的问题时可以用前一层的结果”可以理解为“归来”。“递去”其实就是一个不断分解问题的过程,“归来”就是一个不断解决问题的过程。

2.递归需要满足的三个条件

递归需要满足的三个条件,也就是说什么样的问题可以使用递归去解决。
1.一个问题的解可以分成多个子问题的解
2.这个问题与分解之后的子问题,除了数据规模,求解思路完全一样
3.存在递归终止条件

3.如何用递归算法解决问题

3.1 关注点

1.递归的终止条件
2.每一级递归需要做什么(既然能够使用递归算法来解决,就表示每级递归要做的事是一样的)
3.需要返回什么

3.2 例子

可以看参考资料中的第一篇。
在理解或者解决递归问题的时候,切记不要陷入去理解每调用一次方法的时候具体是什么样的。个人觉得在处理递归问题的时候还是应该从宏观的角度去理解。
还有所谓的递推公式其实就是每一级或者说每一层需要做的事。

4.使用递归的优缺点

4.1优点

递归代码有什么优点呢,优点就是递归代码表达力强,写法简洁。(相比缺点,个人感觉优点好微不足道)

4.2缺点

缺点就是空间复杂度高,有堆栈溢出的风险,存在重复计算等问题。在时间效率上,当函数调用的数量较大时,时间成本就很大。在空间上也会有很大的开销。

4.3还有值得注意的地方

  • 递归代码要警惕堆栈溢出
    编写递归代码的时候,可能会遇到堆栈溢出的问题。堆栈溢出会造成系统性崩溃。在函数调用的时候,Java虚拟机会使用栈来保存函数的临时变量。每调用一个函数,都会将临时变量封装为栈帧压入内存栈中,等函数执行完成返回时才会出栈。如果递归求解的数据规模很大,调用层次很深,一直压入栈,就会有堆栈溢出的风险。(感觉这块并没能理解很好,需要到时去学一下jvm再对比一下递归代码和非递归代码的区别,届时会补充)。
  • 递归代码要警惕重复计算
    在某些情况下,使用递归解法可能会存在重复计算的问题,这个具体可以看参考资料里面的第二篇。那么如何解决重复计算的问题呢?可以使用一个散列表来存储计算过的值,当需要计算某个值的时候,先去散列表中看下是否存在该值,如果不存在则开始计算。

5.参考资料

  1. 3道题彻底搞定:套路解决递归问题
  2. 递归:如何用三行代码找到“最终推荐人”?
  3. 汉诺塔问题详解–递归实现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值