zoukankan      html  css  js  c++  java
  • JavaScript中的递归

    JavaScript递归

    1.递归定义

    递归简而言之就是一个函数调用本身或者两个函数相互调用,我们只讨论第一种情况,需要注意的是, 递归是一个比较难以理解的概念,看不懂, 不理解, 太正常了,这需要时间来, 慢慢搞懂它

    注意:接下来的例子都只是例子而已, 实际不会这么写代码,递归有适用的场景, 但不会用来求阶乘这样的事情,只是为了简化描述才用了这个例子

    (1)递归求阶乘

     1 var fac = function(n) {
     2     // 如果 n 是 0 则返回 1
     3     // 这是递归终止的条件, 必须要有, 否则无限递归了
     4     if(n == 0) {
     5         return 1
     6     } else {
     7         // 如果 n 不为 0, 返回 n * fac(n-1)
     8         // 这时候 n 是已知的, fac(n-1) 需要计算
     9         // 于是代码进入下一重世界开始计算
    10         return n * fac(n-1)
    11     }
    12 }
    13 
    14 console.log('递归阶乘', fac(5))  // 120

    (2)递归求斐波那契数

     1 var fib = function(n) {
     2     // 如果 n 是 1 或者 2 则返回 1 作为结果
     3     // 这是递归终止的条件, 必须要有, 否则无限递归了
     4     if(n == 1 || n == 2) {
     5         return 1
     6     } else {
     7         // 如果 n 不为 1 和 2, 返回 fib(n-2) + fib(n-1)
     8         // 这时候 fib(n-2) fib(n-1) 需要计算
     9         // 于是代码进入下一重世界开始计算
    10         return fib(n-2) + fib(n-1)
    11     }
    12 }
    13 
    14 console.log('递归 fib: ', fib(6))  // 8

    2.经典递归

    一共10级楼梯,每次可以走一步或两步,求一共多少种走法,思路:

    要想走到N(N=10)级,可以分为2种情况。

    1. 从n-2级迈两步
    2. 从n-1级迈一步

    那么对于n-2和n-1的情况也是各自分为两种,以此类推。

    那么走法的和就是n-2的走法和n-1的走法之和。

    那么递归到最基本的(当前人在第0阶台阶)

    第0阶台阶:0

    第1阶台阶:1

    第2阶台阶:2(1+1或者2)

    得到公式,也就是斐波那契数列。

     1 var fib = function (n){
     2     if(n == 1){
     3         return 1;
     4     }
     5     else if(n==2){
     6         return 2;
     7     }
     8     else if(n>2){
     9         return fib(n-1) + fib(n-2);
    10     }
    11 }
    12 
    13 console.log(fib(10));

    3.JavaScript递归中的注意问题

    当使用函数表达式来递归时可能会导致一些问题:

     1 // 函数表达式与递归:
     2 var func = function (num) {
     3     if (num<=1){
     4         return 1;
     5     }      
     6     else{
     7         return num * func(num-1);
     8     }
     9 };
    10 var anotherFunc = func;
    11 func = null;
    12 console.log(anotherFunc(4));  // 报错!

    出错原因:func变量执行上述操作后为空,结果指向原始函数的引用就只剩下一个,但是在接下来的调用anotherFunc中必须执行func,而func已经不是函数了,所以就导致错误出现,在这种情况下使用aruguments.callee可以解决这个问题

    aruguments.callee:是一个指向函数的指针,因此可以用它来实现对函数的递归调用

     1 // 函数表达式与递归:
     2 var func = function (num) {
     3     if (num<=1){
     4         return 1;
     5     }      
     6     else{
     7         return num * arguments.callee(num-1);
     8     }
     9 };
    10 var anotherFunc = func;
    11 func = null;
    12 console.log(anotherFunc(4));  // 24

    另外arguments.callee可以实现匿名函数的递归调用:

     1 // 匿名函数的递归调用
     2 (
     3     function (count) {
     4         if(count<=3){
     5             console.log(count);
     6             arguments.callee(++count);
     7         }
     8     }
     9 )(0);
    10 
    11 // 输出结果: 0 1 2 3

    4.尾递归

    尾递归:是一种在函数的最后执行递归调用语句的特殊形式的递归

    尾递归示例:

    1 var factorial = function(i, a) {
    2     a = a || 1;  // 1是默认值
    3     if (i < 2) {
    4         return a;
    5     }
    6         // 返回自身调用的结果 -》 尾递归 -》JavaScript没有对这种递归做优化 
    7     return factorial(i - 1, a * i);
    8 };
    9 document.writeln(factorial(4));  // 24
  • 相关阅读:
    python flask api
    理解傅里叶变换
    数学建模笔记
    (java)Ansj分词器,Stanford分词器,Jieba分词器,NLPIR汉语分词系统
    《数学之美》读书笔记
    浅谈对机器学习方法(决策树,SVM,knn最近邻,随机森林,朴素贝叶斯、逻辑回归)的理解以及用sklearn工具实现文本分类和回归方法
    《大话数据挖掘》学习笔记——案例教学法
    py调用另一个py
    ros树梅派4bmpu6050
    cleaningrobot_planing
  • 原文地址:https://www.cnblogs.com/wyb666/p/9335931.html
Copyright © 2011-2022 走看看