什么叫递归: 自己调用自己
function foo() {
foo();
}
foo();
//上面是个以死递归
学习递归的目的是什么?即学会如何写递归, 以及如何跳出递归防止死递归,
所以学习递归有两个重要的点:
1, 什么时候递归, 即什么时候调用自己
2, 什么时候跳出
1> 什么时候递归
例子 1. 兔子数列( fibonacci 数列 )
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
如果要计算第 n 项, 就是 在计算 第 n-1 项 + 第 n-2 项
假设有一个函数 fib, 这个函数调用 fib(n) 就是在计算 兔子数列的 第 n 项
var n1 = fib( 3 ); // 计算第 3 项
var n2 = fib(2) + fib(1); // 等价
即写 fib(3) 就相当于写 fib(2) + fib(1)
即 调用函数 fib(3) 就是返回 fib(2) + fib(1)
即得到递归的结构
function fib( n ) {
return fib( n - 1 ) + fib( n - 2 );
}
2> 考虑跳出就是在考虑给出条件的临界点
fibonacci
0 1 2 3 4 5 ...
1 1 2 3 5 8 ...
假设n从0开始
当n=0时,函数执行结果为1:
当n=1时,函数执行结果为1;
当n=2时, 从上面的例子1中得出 ,函数执行结果为2 即fib( n - 1 ) + fib( n - 2 );
临界条件就是结束递归的条件, 那么如果需要递归就是调用自己
如果要结束递归, 就是考虑结束函数, 或返回结果,
所以得出如下函数:
function fib( n ) {
if ( n < 0 ) throw new Error( ' 数字不允许小于 0 ' );
if ( n === 0 || n === 1 ) return 1;
return fib( n - 1 ) + fib( n - 2 );
}
for ( var i = 0; i <= 10; i++ ) {
console.log( fib( i ) );
}
结果如下面:
i=0 1
i=1 1
i=2 2
i=3 3
i=4 5
i=5 8
i=6 13
i=7 21
i=8 34
i=9 55
i=10 89
例子2 利用这个分析方法, 分析 求 n 的 阶乘,
所谓 n 的阶乘就是 从 1 累成到 n. 1! = 1, 2! = 1*2, 3! = 1*2*3, ...
假定 f(n) 就是计算 f(n-1) * n
function f( n ) {
return f( n - 1 ) * n;
}
同样的方法分析阶乘
function f( n ) {
if ( n === 1 ) return 1;
return f( n - 1 ) * n;
}
// 循环的版本
function f2( n ) {
var sum = 1;
for ( var i = 1; i <= n; i++ ) {
sum *= i;
}
return sum;
}
for ( var i = 1; i <= 10; i++ ) {
console.log( f( i ) + "------" + f2( i ) );
}
结果如下面:
2------2
6------6
24------24
120------120
720------720
5040------5040
40320------40320
362880------362880
3628800------3628800
例子3 利用递归分析化归的思想计算求 n 的 m 次方
power(n, m)
1, 假定已经实现 函数名为 pw( n, m )
2, 如果要计算 n^m 次方
3, 例如将其转换为 n^(m-1) * n
n^k * n^(m-k)
2^2 = 2^1 * 2^1
4, 所以化归就可以得到
pw( n, m - 1 ) * n
function pw( n, m ) {
return pw( n, m - 1 ) * n;
}
5, 临界条件
假定 m >= 0
if ( m == 0 ) return 1;
6, 整合
function pw( n, m ) {
if ( m == 0 ) return 1;
return pw( n, m - 1 ) * n;
}
for (var i = 0; i < 10; i++ ) {
console.log( Math.pow( 2, i ) + ", " + pw( 2, i ) );
}
这里顺便介绍一下Math.pow(n,m)这是Math对象提供的一个方法,表示n的m次方
结果如下面:
1, 1
2, 2
4, 4
8, 8
16, 16
32, 32
64, 64
128, 128
256, 256
512, 512