关于递归(Recursion)
- 指在函数的定义里使用函数自身的方法,用于描述以自相似方法重复事物的过程
- 在编程上,它是一种便于理解的心理模型:设定一个边界条件,如果达到则返回结果;如果没有达到,就简化问题,解决更加容易的问题,并且将结果组装成原始问题的解决方法,再返回这个解决方法
- 许多数学函数可以用递归来表示,但是它具有较高的开销
- 典型的递归入门例子:斐波那契数列
斐波那契数列(fibonacci)
1 | function fibonacci(n) { |
Memoization可以优化递归的原理
- 递归是一种循环,会有很大的开销
- 如果把已经计算过的结果保存下来,直接返回而不是重新执行函数,那么就能大大提高递归的效率
- Memoization的核心思想就是建立一个散列,然后把递归问循环里的计算结果记录下来,循环中发现重复的计算就直接获取结果。
比如用Memoization优化fibonacci的递归计算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27var fib = {
// 一般的就这样
fib: function (n) {
if (n == 0 || n == 1)
return 1;
return this.fib(n - 1) + this.fib(n - 2);
},
// 下面会用Memoization来优化
fib_memo: function (n) {
if (n == 0 || n == 1)
return 1;
return this.fib_memo(n - 1) + this.fib_memo(n - 2);
},
}
// 写成通用的包装函数
function Memoize(func, obj) {
var obj = obj || window,
func = obj[func],
cache = {};
return function () {
var key = Array.prototype.join.call(arguments, '_');
if (!(key in cache))
cache[key] = func.apply(obj, arguments);
return cache[key];
}
}
fib.fib_memo = Memoize('fib_memo', fib);