美文网首页
递归那些事

递归那些事

作者: 哪树繁花 | 来源:发表于2017-09-10 18:23 被阅读10次

    果然还是想递归能让脑子转起来

    上一次写递归应该是在学校认识实习的时候写扫雷用到的,因为需要遍历地图,当时自己写的时候用队列写的广度优先搜索(BFS),因为相对于比较费脑的递归,用队列好想的多了,但碍于指导老师的要求还是又用递归写了一遍。再往前的话,就是acm的时候做题用到的了,但也很少,能用循环解决的干嘛要用递归呢(其实更重要的原因是当时对递归真的不是很理解,看别人的代码都不一定能看懂,别说自己写了)。恩,再往前应该就没有了。

    好了,来看今天的问题吧

    “所有的递归都能用循环实现。”这句话不是我说的,网上赞同的很多,反对的也不少。但就目前我遇到的情况,都能把递归转换成循环,换句话说吧,“我用过的循环基本都能转换成递归”,因为我都是优先用循环,做完之后闲着没事再去琢磨用递归实现。
    来分析下怎么写一个递归
    首先,递归要有结束条件,不然就是死循环
    其次,你想让他循环干甚么
    最后,返回值应该是什么
    不看最后一点的话,跟写循环一样,其实真的差不多,下面通过几个问题来理解一下

    1. 递归求阶乘
      先看看用循环怎么做吧
      求n的阶乘,循环n次,累乘就好了
    var n = 5;
    var sum = 1;
    for(var i = n; i > 0; i--){
        sum *= i
    }
    alert(n+"的阶乘是:"+sum);
    

    下面是递归
    首先,求n的阶乘的话,自然是从n一直乘到1,所以结束条件是n>1,
    其次,当前数乘上他前面一个数的阶乘就是当前数的阶乘
    最后,每次的返回值都是当前数乘上前一个数的阶乘,当当前数为1的时候,返回值就是1
    最后的结果就是这样,想!一定要动脑子想!

    function deal(n){
        if(n > 1){
            return n * deal(n - 1);
        }
        return 1;
    }
    
    1. 递归求斐波那契数(第一位和第二位为1,往后的都为前两位的和,1 1 2 3 5 8 13 21 34....)
      首先,已知第一位和第二位都是1,所以当n为1和2的时候我们都返回1就行了,故结束条件是n>2
      其次,公式是:当前项的值为其前两项的和,那就是:f(n) = f(n-1) + f(n-2)
      最后,n为1和2的时候我们都返回1,否则返回f(n-1) + f(n-2)
    function f(n){
        if(n > 2){
            return f(n-1) + f(n-2);
        } else {
            return 1;
        }
    }
    
    1. 递归求组合数(C(M,N)是从M个物品中任选N个的方法,详情点这里
      求组合数的公式:C(m, n) = C(m-1, n) + C(m-1, n-1)
      这里的m是在公式里下面那个比较大的数,n是比较小的数。当时我自己写完测试的时候给弄反了,怎么弄结果都不对,最后看了下公式,原来是n和m弄反了。直接上代码了,思路跟之前的一样。唯一要注意的就是结束条件,当n的值为0,或者是n等于m的时候,组合数的值为1
    function deal(m, n){
        if(m && m < n){
            return deal(m-1, n) + deal(m-1, n-1);
        } else {
            return 1;
        }
    }
    

    相关文章

      网友评论

          本文标题:递归那些事

          本文链接:https://www.haomeiwen.com/subject/xidtsxtx.html