zoukankan      html  css  js  c++  java
  • 递归

    做了一段时间的题,越来越感觉想明白递归这件事真的很重要,而且这件事并不是一两天就可以彻底明白所有题目,所有种递归。

    学递归更多是通过不断训练,日积月累形成这种递归的思维,因为迭代、递推是与我们正常运算思维相同的,而递归是完全相反的。

    比如算阶乘这件事,n!=1*2*3*……*n一般想到的都是从1*2开始算起,再用结果依次向后乘。这是迭代。

    而递归怎么算?递归是想,我要算n的阶乘我直接用算式前边(n-1)!的结果乘n就好了。

    而(n-1)!该怎么算?那我把(n-2)!结果乘n-1就好了。

    ……

    以此类推,最后一直道2!=1*2无法再分解了;然后再将结果逐层返回。这是递归。

    为什么我们思维更习惯迭代?

    按照上面的例子顺理成章的想,主因是我们懒,原因如下:

    用迭代时,我的想法是只算1*2=2;然后再取后边一个数,再算2*3=6……这样每次只要存一个数,取一个数再做一次运算。

    用递归时,造成你我想到n!=(n-1)!*n就烦的是什么?是因为对你来说,(n-1)!他就是个未知数,所以要求他就得再往上找。但是这个n他就要记住,到了下一层时n-1这个数也要记……直道最后一层,1*2=2了;才能返回去前一层做上一次的的运算,当然前提是你得记住前一层的状态。

    因为这个简单例子里边都是有序的,差别并不大,但是做其他的递归时,可能涉及到其他许多变量或者说事儿的状态要存储,而我们习惯于能记得多简,就记得多简。

    这样大脑思考和运算的感觉更轻松。而且大多的递归都能通过迭代做到(不讨论优劣)。所以我们本能的讨厌递归这种思维,而偏爱迭代。

    在算法上更是如此,所以新手碰到递归时一般都不太愿意去做orz。长久以后会发现根本写不好递归,或者说对递归这件事都是畏惧心理,那就完蛋了。

    那怎么去学递归?(以下观点纯属个人感觉,走火入魔,后果自负)

    ①:我觉得首先得建立对 递归的感觉——它是对的,是严谨正确的。

    这一点用类似数学归纳法就可以证明

    https://www.cnblogs.com/LiCheng-/p/8206444.html这位兄弟有现成的。

    思路也比较简单。用Paul Graham的话来理解

      1. 当n=0, 1的时候, 结果正确.
      2. 假设函数对于n是正确的, 函数对n+1结果也正确.
        如果这两点是成立的,我们知道这个函数对于所有可能的n都是正确的。

    另外,我认为所有递归和迭代都可以借助栈或存储空间来互相改写(不考虑改写后效率),所以可以理解为用迭代可以实现的,用正确的递归肯定也能正确实现。(这点有待考察)

    ②:多写多练,形成一种思维好像没有更好的方式了,怎么绕不开练习,多写代码多想,这个方法简单粗暴好用!

    如何写递归?递归有套路吗?


    写递归到是有固定的几点。固定套路真的还没发现orz,真是什么样的递归都有。

    不过写的时候注意这几点肯定没错:

    ①:我这个算法用递归到底对不对->是不是对于所有情况都能用相同方式拆分成子问题?是不是求解方式适用于所有情况?

    ②:写主函数时先写大体框架,用自顶向下的方法写(这是刘汝佳说的)。

    ③:要时刻记得把所有情况都想清楚:一般情况,特殊情况1,特殊情况2,……,一定要做到严谨,所有情况下算法都正确。

    ④:递归边界(基)一定要明确且正确。

    关于递归函数的返回值和参数:

    先说不带引用的:因为只传址,参数可以看成对当前层的状态的描述,比如根据这些状态判断是否继续递归。

            而返回值可以是作为上一层计算的结果,例如阶乘的那个例子。

    另外,胡思乱想了一下,我们所处的世界大多都是两面相对的,阴阳,正负,对错,物质和反物质,那么有正向思维就有逆向思维。想想既然这些都是人的主观规定,

    那么就可以少一点对逆向思维的“特殊”的感觉(毕竟只是你认为的普通思维的相对面),这样也解释了许多很难很难的算法用递归来写非常简单有效。可能是用递归这个从”反面“走的思维,来解决从“反面”来的问题更合适呢。(上边这些纯属是个人纯瞎想,没事别瞎看)。

    以上

    还有很多很多要总结的,以后遇到想到再慢慢来吧。

  • 相关阅读:
    Myeclipse快捷键
    Resharper 的快捷键
    jQuery模块自由组合方案
    CTE
    Nhibernate3以上单元测试
    第三方控件下载篇
    10 个 Visual Studio 原生开发的调试技巧
    Nhibernate为hbm.xml配置文件添加智能提示(VS2010)
    Win7下nginx默认80端口被System占用
    Nginx本地配置
  • 原文地址:https://www.cnblogs.com/worldcreator-zh/p/10540180.html
Copyright © 2011-2022 走看看