位置:首页 > 软件操作教程 > 编程开发 > JavaScript > 问题详情

JavaScript 尾递归

提问人:刘团圆发布时间:2020-11-25

■知识点

    尾递归是递归的一种优化算法,它从最后开始计算,每递归一次就算出相应的结果,即函数调用出现在调用函数的尾部,因为是尾部,所以就不用去保存任何局部变量,返回时调用函数可以直接越过调用用者,返回到调用者的调用者。

■实例设计

下面是阶乘的一种普通线性递归运算。

function f( n ){

    return ( n == 1 ) ? l : n * f( n - l );

}

console.log(f (5) ) ;        //120

使用尾递归算法后,则可以使用如下方法。

function f ( n, a ){

    return ( n==l ) ? a : f( n - l, a * n );

}

console.log( f (5 , 1) ); //120

当n = 5时,线性递归的递归过程如下。

f(5) = {5 * f (4) }

     = {5 * {4 * f(3)}}

     = {5 * {4 * {3 * f(2) }}}

     = {5 * {4 * {3 * {2 * f(1) } } } }

     = {5 * {4 * {3 * {2 * 1}}}}

     = {5 * {4 * {3 * 2}}}

     = {5 * {4 * 6}}

     = {5 * 24}

     = 120

而尾递归的递归过程如下。

f(5) = f(5, 1)

     = f(4, 5)

     = f(3, 20)

     = f(2, 60)

     = f(1, 120)

     = 120

从上面的代码中很容易看出,普通递归比尾递归更加消耗资源,每次重复的过程调用都使得调用链条不断加长,系统不得不使用栈进行数据保存和恢复,而尾递归就不存在这样的问题,因为它的状态完全由变量n和a保存。

■小结

    从理论上分析,尾递归也是递归的一种类型,不过它的算法具有迭代算法的特征。上面的阶乘尾递归可以改写为下面的迭代循环。

var n = 5 

var w = 1;

for ( var i = 1; i <= 5; i ++ ) {

    w = w * i;

}

console.log ( w );

尾递归由于直接返回值,不需要保存临时变量,所以性能不会产生线性增加,同时JavaScript引擎会将尾递归形式优化成非递归形式。

继续查找其他问题的答案?

相关视频回答
回复(0)
返回顶部