六、递归(Recursion)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012736685/article/details/83119503

一、递归概述

应用:DSF深度优先搜索、前中后序二叉树遍历等

三个条件:

  1. 一个问题的解可以分解为几个子问题的解
  2. 该问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
  3. 存在递归终止条件


写递归代码的关键:

  • 如何将大问题分解为小问题的规律 =》写出递归公式
  • 确定终止条件
  • 将递推公式 和 终止条件 转化为codes

优点:表达力强、非常简洁;
缺点:空间复杂度高、有堆栈溢出的风险、存在重复计算、过多的函数调用耗时等问题。

二、注意

1、警惕堆栈溢出

影响:堆栈溢出 ==》系统性崩溃

原因:系统栈或虚拟机栈空间一般都不大。若递归求解的数据规模很大,调用层次很深,一直压入栈,就会有堆栈溢出的风险。

措施:

  1. 设置递归调用的最大深度,也就是递归调用超过一定深度之后,就不继续再递归下去,而是直接返回报错。==》不是很实用
  2. 通过在堆上模拟实现一个函数调用栈,手动模拟压栈、出栈的过程,这样就没有系统栈大小的限制。

2、警惕重复计算

例如:斐波那契数。eg:1、1、2、3、5、8、
在这里插入图片描述
从图中可得==》f(3) 就被计算了很多次,这就是重复计算问题。

措施:

  1. 可以通过一个数据结构(例如散列表)来保存已经求解过的 f(k) 。当递归调用到 f(k) 时,先确定是否已经求解过了,若是则直接取数,否则再进行计算。

3、时间和空间复杂度

  • 时间:调用的数量较大时 ==》时间成本
  • 空间:每递归一次就会在内存栈中保存一个现场数据。

4、递归代码 =》非递归代码

猜你喜欢

转载自blog.csdn.net/u012736685/article/details/83119503