0
点赞
收藏
分享

微信扫一扫

0 4 递归(Recursion)


◼ 递归:函数(方法)直接或间接调用自身。是一种常用的编程技巧

◼ 如果递归调用没有终止,将会一直消耗栈空间

最终导致栈内存溢出(Stack Overflow)

◼ 所以必需要有一个明确的结束递归的条件

也叫作边界条件、递归基

 

1.递归的基本思想

◼ 拆解问题

把规模大的问题变成规模较小的同类型问题

规模较小的问题又不断变成规模更小的问题

规模小到一定程度可以直接得出它的解 n n – 1 n – 2 .... 2 1

◼ 求解

由最小规模问题的解得出较大规模问题的解

由较大规模问题的解不断得出规模更大问题的解

最后得出原来问题的解

◼ 凡是可以利用上述思想解决问题的,都可以尝试使用递归

很多链表、二叉树相关的问题都可以使用递归来解决

✓ 因为链表、二叉树本身就是递归的结构(链表中包含链表,二叉树中包含二叉树)

 

2.递归的使用套路

① 明确函数的功能

先不要去思考里面代码怎么写,首先搞清楚这个函数的干嘛用的,能完成什么功能?

② 明确原问题与子问题的关系

寻找 f(n) 与 f(n – 1) 的关系

③ 明确递归基(边界条件)

递归的过程中,子问题的规模在不断减小,当小到一定程度时可以直接得出它的解

寻找递归基,相当于是思考:问题规模小到什么程度可以直接得出解?

 

3.相关练习

     1.练习1 – 斐波那契数列(详细优化查看学习资料)

◼ 斐波那契数列: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 项斐波那契数

0 4 递归(Recursion)_算法

◼ 根据递推式 T n = T n − 1 + T(n − 2) + O(1),可得知时间复杂度:O(2^n)

◼ 空间复杂度:O(n)

递归调用的空间复杂度 = 递归深度 * 每次调用所需的辅助空间

     2.练习2 – 上楼梯(跳台阶)

     ◼ 楼梯有 n 阶台阶,上楼可以一步上 1 阶,也可以一步上 2 阶,走完 n 阶台阶共有多少种不同的走法?

     假设 n 阶台阶有 f(n) 种走法,第 1 步有 2 种走法 

      ✓ 如果上 1 阶,那就还剩 n – 1 阶,共 f(n – 1) 种走法 

      ✓ 如果上 2 阶,那就还剩 n – 2 阶,共 f(n – 2) 种走法

      所以 f(n) = f(n – 1) + f(n – 2)

0 4 递归(Recursion)_算法_02

0 4 递归(Recursion)_数据结构_03

 

​​70. 爬楼梯​​

3.练习3 – 汉诺塔(Hanoi)(详细题解查看学习资料)

◼ 编程实现把 A 的 n 个盘子移动到 C(盘子编号是 [1, n] )

每次只能移动1个盘子

大盘子只能放在小盘子下面

 

◼ 其实分 2 种情况讨论即可

当 n == 1时,直接将盘子从 A 移动到 C

 当 n > 1时,可以拆分成 3大步骤

 

① 将 n – 1 个盘子从 A 移动到 B

② 将编号为 n 的盘子从 A 移动到 C

③ 将 n – 1 个盘子从 B 移动到 C

✓ 步骤 ① ③ 明显是个递归调用

 

0 4 递归(Recursion)_数据结构_04

 

递归转非递归的详细方法查看学习资料

 

举报

相关推荐

0 条评论