摘要:冴羽的博客学习递归
递归
程序调用自身的编程技巧称为递归(recursion)。例如:
阶乘
1 | function factorial(n) { |
可以看出:构成递归需具备边界条件、递归前进段和递归返回段,当边界条件不满足时,递归前进,当边界条件满足时,递归返回
递归的特点:
1.大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
2.不能无限制调用自身,必须有出口——明确的边界条件
尾调用
尾调用就是指某个函数的最后一步是调用另一个函数
例如:
1 | // 尾调用 |
分析下执行上下文栈变化:
1 | // 伪代码 |
结论:使用尾调用只存在一个调用记录,所以永远不会发生“栈溢出”错误
1 | // 非尾调用,如上面的阶乘 |
分析下执行上下文栈变化:
1 | // 伪代码 |
结论:函数调用自身,称为递归。如果尾调用自身,就称为尾递归。普通递归非常耗费内存,递归层次过多会导致“栈溢出”,而利用尾递归则可以避免
优化阶乘函数:
1 | function factorial(n, res) { |
利用占位偏函数:
1 | var newFactorial = partial(factorial, _, 1) |