在这个问题上的继续延申,递归和尾递归的概念和区别
[Lua] 纯文本查看 复制代码 local fact
fact = function (n)
if n == 0 then
return 1
else
return n*fact(n-1)
end
end 以上是递归,不是尾递归。因为n*fact(n-1)在当前层时并不能得到结果,而是需要递结束后返回时才能够计算得到结果。递归是要通过“递”将算法传递下去,再通过“归”将值一层层返回,所以每递一次就要开一个栈,用于保存算法,直到得到返回值经过计算得到结果,再结束这些栈。当递的层数过长,将会导致栈溢出。
以下是改造成尾递归
[Lua] 纯文本查看 复制代码 local fact
fact = function (n,acc)
if n == 0 then
return acc
else
return fact(n-1 , n*acc)
end
end
对比以上,尾递归的特点就是在“递”的时候就已经就算完毕,递下去的是值,因此不用在递的过程中保存算法等信息,也即不用开栈。这样的话不论多少层都可以进行,不存在溢出的问题,同时保持了递归易理解,编写简洁的特点。以上还可以进行优化成一个参数:
[Lua] 纯文本查看 复制代码 function fact(n)
local function fact_helper(n, acc)
if n == 0 then
return acc
else
return fact_helper(n - 1, n * acc)
end
end
return fact_helper(n, 1)
end
|