JavaScript中的递归

JavaScript递归函数

1.递归定义优化

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

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

 

(1)递归求阶乘code

 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)递归求斐波那契数blog

 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级楼梯,每次能够走一步或两步,求一共多少种走法,思路:ip

要想走到N(N=10)级,能够分为2种状况。it

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

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

那么走法的和就是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
相关文章
相关标签/搜索