递归和闭包的深入研究

 递归

递归的定义:就是在函数内运行的时候调用自己

           在使用递增策略时,必须有一个明确的条件,成为递归出口

<script>
    //求1-n的和
    function fn ( n ) {
        /*
        * 执行步骤:(1)fn(5)调用执行函数体代码   进行判断,判断不成立, 执行下方调用代码,  执行完毕之后返回4次执行的结果
        *
      *
*/ if ( n == 1 ) { return 1 } return fn ( n - 1 ) + n } console.log ( fn ( 5 ) ) </script>
  /*
     * 第一:每一级的函数调用都有它自己的变量。
        第二:每一次函数调用都会有一次返回,并且是某一级递归返回到调用它的那一级,而不是直接返回到fn()函数中的初始调用部分。
        第三:递归函数中,位于递归调用前的语句和各级被调函数具有相同的执行顺序。例如在上面的程序中,打印语句位于递归调用语句之前,它按照递归调用的顺序被执行了4次,
                  即依次为第一级、第二级、第三级、第四级。
        第四:递归函数中,位于递归调用后的语句的执行顺序和各个被调函数的顺序相反。例如上面程序中,打印语句#2位于递归调用语句之后,
                 其执行顺序依次是:第四级、第三级、第二级、第一级。(递归调用的这种特性在解决涉及到反向顺序的编程)
         第五:虽然每一级递归都有自己的变量,但是函数代码不会复制。
        第六:递归函数中必须包含终止递归的语句。通常递归函数会使用一个if条件语句或其他类似语句一边当函数参数达到某个特定值时结束递归调用,如上面程序的if(n == 1)。
     *
     * */
递归和反向计算
这里讨论一下使用递归处理反向问题,这类问题使用递归比使用循环更加方便。通过一个例子来体会:编写一个函数将一个十进制整数准换成二进制。

关于进制准换的一般思路,可以移步这里。

上面博客是用循环实现的,用循环实现需要额外的空间来保存转换后的每一位,根据“递归的基本原理”第四条可以得知用递归来求不需要自己申请额外空间,只要我们把转换后的位的输出语句写在递归式之后,就能逆序输出。

用递归实现算法时,有两个因素是至关重要的:递归式和递归边界。 
在这个例子中,根据上面给出的链接方法,可以很容易的得出递归式:to_binary(n/2)。 
那么递归边界是多少呢?是n<2。因为当n>=2时,就需要一位二进制位来表示。所以只有被2除的结果小于2时才停止计算。每次除以二就可以得到一位,直到得到最后一位为止。

猜你喜欢

转载自www.cnblogs.com/myStudyCareer/p/9426800.html