剖析递归(python汉诺塔代码解析),想不理解都难

“君不见黄河之水天上来,奔流到海不复回,君不见高堂明镜悲白发,朝如青丝暮成雪”

开始

递归?什么是递归?自己掉自己?可以说递归是一种思想,一种“分而治之”的思想,俗话说的好啊:“大事化小,小事化了。”就这意思,把大问题分成构成他的小问题解决。会不会用另说,我们的先理解吧。
其实概念啥的不用多说,相信大家都知道,主要在于理解。
废话完毕!!

理解

举啥栗子呢?斐波那契数列?阶乘?你信吗?
我们来看一个阶乘的栗子

int fun(int n){    
      if (n == 0)  return 1;  
      return n * Factorial(n - 1);
}

这很好理解啊一张图解决问题
在这里插入图片描述
平时我们的习惯是先算F(0)然后一直到F(n),这次反过来了。这个也不难。
我在学习时遇到一个二叉树的递归,当时就给弄懵了,可能有点蠢,理解了好一会可算搞明白了
就拿Leetcode的一道题:求二叉树的最大深度
递归主要的就是寻找终止条件,以及返回值是啥,不然无线循环了或者没有返回值,那还写啥,回家种地吧 。
终止条件就是叶子节点呗,叶子节点的左右子树为空,这是终止节点,
返回值当然就是深度了,当然我们的反着来,叶子节点的深度为0,然后父节点存放其左右节点的最大深度,这样返回到根节点的就是最大深度了
代码

class TreeDepth{
    public int depth(TreeNode root) {
        //到叶子节点返回当前深度0
        if(root == null){
            return 0;
        }
        //root的左、右子树的最大深度
        int leftDepth = depth(root.left);
        int rightDepth = depth(root.right);
        //返回的是左右子树的最大深度+1
        return Math.max(leftDepth, rightDepth) + 1;
    }
}

刚开始我理解的是先左子树,然后左子树的两个子节点,以此类推,后面发现不对,这代码得按顺序执行啊。。然后就有点懵了。。
上图
在这里插入图片描述
步骤已经很明确了,和使用深度优先遍历二叉树很相似,或者说一样

  • 当我们执行代码时先执行leftDepth ,所以就会一直循环调用左子树,先后遍历a,b,d,然后到d的leftDepth 时,其left为空,这样是不是就有返回值了,leftDepth 的值是不是为0,然后因为leftDepth 有值了,是不是该执行rightDepth 那条语句了,执行完该语句是不是又产生了调用,又有leftDepth 和rightDepth 当两个都有返回值了,就证明该节点的左右子树就都有返回值了,我们取其中大的那个,然后再加一是不是就是该节点存放的最大深度,以此内推。。。
  • 参考: https://blog.csdn.net/allenchenhh133/article/details/80291252

汉诺塔

最近有遇到了汉诺塔,我都感觉自己脑子what。。。。
汉诺塔是啥?我也不知道。这应该不需要解释了吧,源于印度的传说,如果一秒移到一次的话需要5800亿年,而太阳系大约还有100-150亿年。。指数级别的增长是非常恐怖的。
我还是描述一下问题:3根柱子,有一根柱子上放着n个圆盘,从上到下,从小到大,要求将这n个圆盘移到到另一根柱子,一次只能移到一个圆盘,圆盘只能大的在下,小的在上。
python代码

def move(n, a, b, c):
    if n == 1:
        print(a, "--->", c)
        return
    else:
        # 将n-1个盘子挪到b
        move(n-1, a, c, b)
        # 将最后一个盘子挪到c
        move(1, a, b, c)
        # 将b的n-1个盘子挪到c
        move(n-1, b, a, c)

if __name__ == '__main__':
    move(3, "A", "B", "C")

大概思路就是先将a上面的n-1个盘子,借助三根柱子移动到b,然后将最大的一个移动到c,然后在以同样的思路借助a,b,c三根柱子,将b上面的圆盘的n-1个(相对于总的来说是n-2)圆盘移动到a,再把第二大的圆盘移动到c,以此类推。。。(这应该很清晰了吧)
网上找的一张图
在这里插入图片描述
思路应该还是很好理解的,你就是在脑海里从移动两个,到移动三个,到移动四个,想清楚整个过程就很清楚了
然后我看着上面的代码,执行的结果是这样的
在这里插入图片描述
第一步结果就给我卡住了,我知道从思路上来看,是应该a到c,但我看代码掉坑里了,总感觉是a-b,然后在知乎上才搞清楚了,
在这里插入图片描述
看完这张图瞬间就跳出坑了
感谢知乎大佬的图
https://www.zhihu.com/question/37152936

over

你爱了吗?

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值