递归对于初学者是一个挺难理解的思想这里有两个经典实例 -- 阶乘 && 斐波那契数列
一个阶乘(普通函数):
function fact(n){ var mul = 1; if(n < 0){ console.log('error'); } for(var i = 1; i <= n; i ++){ mul *= i; } console.log(mul); }
--------------------------------------递归分割线--------------------------------------------
function mul(x) { if (x == 1 || x == 0) { return 1; }
// 重要代码!!! return x * mul(x - 1); }
这么多代码, 搞定;
再回想一下斐波那契数列, 如果用普通方法写的话:
var first = 1, second = 1, third; // 我们需要定义三个游标, 因为斐波那契数列就是这个数等于前两个数相加; if (n == 1 || n == 2){ console.log(1); }else{ for(var i = 0; i < n - 2; i ++){ third = first + second; first = second; // 游标向后移动一位 second = third; } } console.log(third); // 打印就行了
大概要写这么多
--------------------------------------递归分割线--------------------------------------------
而递归呢:
function feb(n) { if (n <= 0){ console.log('error'); // 斐波那契数列从1开始 } if (n == 1 || n == 2){ return 1; // 返回值是递归的灵魂 }
// 重要代码 !!! return feb(n - 1) + feb(n - 2) }
这里分析一下斐波那契数列, 另一个方法类似:
例如, 我们调用feb(5)
只分析重要代码:
返回feb(5) = feb(4) + feb(3);
对于feb(4) = feb(3) + feb(2);
而且feb(3) = feb(2) + feb(1);
feb(2) 直接返回1, feb(1)也一样
再一层一层往上套, 结果就出来了
这样, 就理解递归了吧.
我们可以发现, 递归有以下优点:
1. 更简洁的代码
2. 更符合人类的思想
递归直截了当来说就是找规律的, 找到规律, 有结束条件, 把公式一写就行了;
但是, 递归的缺点也是十分明显 代码执行速度慢, 因为要一层一层嵌套, 又要一层一层返回, 很容易造成内存泄漏;
所以, 比较大的工程里面几乎不会使用递归;