通俗讲:数据结构递归思想

脑容量有限,拒绝花里胡哨

一个递归求阶乘的例子

#如5的阶乘 f(6)=6*5*4*3*2*1
def f(int n) {if  n <= 0 : return 1return n * f(n - 1)
}

如果没有特殊说明,下文都是拿此例子说事

通俗讲:递归

  • 递归就是函数内调用自己 f(n - 1)
  • 一个问题可以分解成具有相同解决思路的子问题才可以使用递归
  • 递归函数必须有结束出口: n <= 9 ,否则你就等着扣工资吧(滑稽)!
  • 函数内调用时参数一致,如调用 f() 是不正确的(f 函数有且只有一个参数)
  • 递归方式可以转换成迭代(遍历)方式
  • return f(n-1) 会继续调用递归,return 1会终止当前递归函数(即结束出口)

记住以上黑体字,你就能解决大部分的递归问题了

递归递归,先递后归

递归的优点和缺点

优点

  • 代码简洁
  • 易于理解,如在树遍历中,递归的实现明显比循环简单。

缺点

  • 每次调用都需要在内存栈中分配空间以保存参数,返回值和临时变量,降低了效率
  • 递归的分解的多个小问题存在重叠的部分,即存在重复计算
  • 栈空间是有限的,当调用的次数太多,可能会超出栈的容量,造成调用栈溢出

综合各方面,迭代的效率更佳,但有些问题用迭代处理更复杂

用迭代思想去思考递归

  1. 循环结束条件 -> 递归结束出口
  2. 循环体-> 处理相同解决方案的子问题
  3. 进行下一次循环->返回调用递归函数

解题心得

  • 一定不要试图跟踪大型递归的过程,否则会你让头脑炸裂,甚至怀疑人生
  • 在调用递归的时候利用整体思想,默认f(n)这个整体已经被求出来了,至于怎么求的由计算机来回溯求出。如上面的求阶乘的例子中 当n=6时 6 * f(5)就默认f(5)=5*4*3*2*1=120已经在草稿纸算过
  • 解题时要清楚递归函数功能、结束出口、要处理的子问题是什么、函数调用位置和次数
    如在求阶乘中:函数功能就是求n的阶乘并返回,结束出口就是n<=1要处理的子问题就是用当前数乘以 n-1的阶乘,递归调用位置为在返回的时候直接调用一次即可

在有触发结束递归的情况下,递归调用=子问题处理+递归调用,也就是说一次递归调用从整体上看是实现函数功能,从局部上看就是处理一次子问题

上例题

例 1:给出一个整数num,反复将num各个位上的数字相加,直到结果为一位数

  • 函数功能:累加各位数直至结果为一位
  • 结束出口: num<10
  • 子问题:将num各位上的数字相加
  • 递归调用位置:在求出num后调用一次
#递归法
def addDigits(self, num: int) -> int:#1递归出口,直到结果为一位数即 num<10if num < 10: return num#2.处理子问题:反复将num各个位上的数字相加temp = str(num)s = 0for a in temp:s += int(a)#3.返回递归调用:没达到需求,继续递归return self.addDigits(s)


例2:斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。

要求:给定 N,计算 F(N)

  • 函数功能:计算 F(N)
  • 结束出口: N == 0 or N ==1
  • 子问题:计算前俩F(n-1)和F(n-2),这里用整体思想,默认这两个已知
  • 递归调用位置:调用2次,即直接返回F(n-1)+F(n-2)
class Solution:def fib(self, N: int) -> int:#结束出口if N == 1 : return 1if N == 0 : return 0#处理子问题(前两者相加)+递归调用return self.fib(N-1)+self.fib(N-2)


例3:汉诺塔问题

解决思路:

  • 首先将最上面的n-1个盘子从A移到B柱子
  • 然后将最下面的一个盘子从A移到C柱子
  • 最后将n-1个盘子从B移到C柱子

注意:递归函数需要处理的子问题是:将最底部的元素移到盘子C中

#主函数
def hanota(self, A, B, C):'''A: List[int] 初始数据列表B: List[int] 辅助移动数据列表C: List[int] 最终移动数据列表return: None'''n = len(A)self.move(n, A, B, C)# 定义move函数移动汉诺塔(递归函数)
#子问题:将A盘子最底部元素借助盘子B移动到盘子C
def move(self,n, A, B, C):#结束条件if n == 1:C.append(A.pop())  #移动最底的元素到Creturn #递归调用+处理子问题(将A的最后一个移到C)self.move(n-1, A, C, B)  # 将A上面n-1个通过C移到BC.append(A.pop())          # 将A最后一个移到C        self.move(n-1,B, A, C)   # 将B上面n-1个通过空的A移到C

C++两个函数可以相互递归吗_通俗讲:数据结构递归思想相关推荐

  1. C++两个函数可以相互递归吗_[算法系列] 搞懂递归, 看这篇就够了 !! 递归设计思路 + 经典例题层层递进

    [算法系列] 搞懂递归, 看这篇就够了 !! 递归设计思路 + 经典例题层层递进 从学习写代码伊始, 总有个坎不好迈过去, 那就是遇上一些有关递归的东西时, 看着简短的代码, 怎么稀里糊涂就出来了. ...

  2. C++两个函数可以相互递归吗_C语言(7)- 递归

    (本文为原创,版权归作者所有) 递归(Recursion) 递归是一种计算方法,它的每一步计算都可以被分解为更小规模的相同的计算,因此一个问题可以通过不断重复的分解来解决.一个典型的例子是计算阶乘N! ...

  3. C++两个函数可以相互递归吗_C语言“最难啃”的三块硬骨头!你知道吗?

    提到C语言很多初学者都觉得,学到中间就进行不下去了,因为碰到了几个硬骨头死活翻不过去,于是很多人给C语言下结论太难了,太靠近底层了,特别是那几块难啃的骨头,直接理解不了,进行不下去. 今天就来说下,最 ...

  4. 三元函数的几何图形一般是_三元表达式,递归,内置函数

    三元表达式 三元表达式仅应用于: 1.条件成立返回一个值 2.条件不成立返回一个值. 若一般函数表达如下 比大小: def max2(x,y):if x>y: returrn xelse:ret ...

  5. 二叉树的递归遍历算法c语言 数据结构,递归创建二叉树c语言实现+详细解释

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 void CreatBiTree(BiTree T) { char a; scanf("%c",&a); if(a=='@') ...

  6. 递归 尾递归_代码简报:递归,递归,递归

    递归 尾递归 Here are three stories we published this week that are worth your time: 这是我们本周发布的三个值得您关注的故事: ...

  7. vue 循环 递归组件_全局组件实现递归树,避免循环引用

    概述 目录分类展示会通常要用到树形结构.本例结合vue的父子组件,采用递归渲染,实现一个基于树的curd小demo 知识点 父子组件递归渲染 class 样式对象写法,CSS伪元素 ::before ...

  8. mysql 实现非递归树_二叉树的非递归前序,中序,后序遍历算法

    #include #include struct tree { char data; struct tree *lchild; struct tree *rchild; }; typedef stru ...

  9. 分别采用递归和非递归方式编写两个函数,求一棵二叉树中叶子节点个数

    分别采用递归和非递归方式编写两个函数,求一棵二叉树中叶子节点个数 #include #include #define MAXSIZE 50 typedef char datatype; typedef ...

最新文章

  1. 2019年智能手机AI要被深度开发,这五项技术将是重点
  2. 解决外部符号错误:_main,_WinMain@16,__beginthreadex
  3. 自制Flash FLV视频播放器
  4. python恶搞表情包-Python开发个人专属表情包网站,表情在手,天下我有
  5. 跟alex学python_跟着Alex学习python
  6. c++ 自定义比较函数,运行时发生segmentation fault
  7. 人工智能会让工作环境变得更公平,还是更压抑?
  8. STM32的ADC通道间干扰的问题
  9. 用户自定义属性表结构设计_属性类型定制及其妙用
  10. Flutter实战一Flutter聊天应用(五)
  11. aix 查看防火墙状态_aix防火墙怎么样设置
  12. 十年Java面向对象编程心路——函数与方法的概念区别
  13. [从零开始学习FPGA编程-55]:视野篇-芯片的制程
  14. 图像检索--联合加权聚合深度卷积特征的图像检索方法
  15. i3型3D打印机制作详解——Marlin固件中文介绍
  16. linux病毒扫描工具,linux病毒扫描工具ClamAV使用
  17. C++ 并发指南-atomic原子变量使用struct(二)
  18. PCIE配置空间设置
  19. 页错误处理 Page Fault Handling
  20. 《热浪球爱战》首映 周秀娜现场超低胸打排球

热门文章

  1. Go两个协程生产消费者模型
  2. repo一个新工程使用步骤
  3. android之sqlite增、删、改,查
  4. 计算机基础(六):内存申请方式
  5. matlab y轴旋转面,Mayavi:绕y轴旋转
  6. 深度学习掩膜_学习资源 | NOAA连接AI与环境科学(九)—海洋环境视频和图像分析教程...
  7. thinkphp5--文章发布后台管理系统
  8. php ccontroller,FineCMS controllers\ApiController.php 函数downAction 任意文件下载
  9. mysql sharding 知乎_分库分表系列(1)-shardingsphere核心概念
  10. layer 子页面提交 刷新父页面 table