|
4#
楼主 |
发表于 20-8-2009 14:35:28
|
只看该作者
现在,我们想要写另一个函数,来计算有名的斐波那契数列。这个数列的一般递归定义是:
函数 Feb 对给出的 整数 n
如果 n<2 返回1
否则 返回 Feb(n-1) + Feb(n-2)
乍一看,这个函数似乎没有办法变成尾递归的。因为尾递归要求最后一步才调用自己,这意味着只能调用一次自己。但是上面的定义中,调用了两次自己。
不过,这只是假象。我们可以想象,虽然每次用较大的参数调用这个函数时,都要调用两次自己,但是我们可以让这些步骤一步一步来:
Feb(n) = Feb(n-1)+Feb(n-2)=(Feb(n-2)+Feb(n-3))+Feb(n-2)= 2*Feb(n-2) + Feb(n-3) = 2*(Feb(n-3)+Feb(n-4)) + Feb(n-3) ........
要彻底尾递归化,我们要把上述过程进行到底:
函数 Feb1 对给出的 整数 n, 整数a 和 整数 b
如 n=0 返回 a
否则 返回 Feb1(n-1, a+b, a)
要理解这个函数,可以想象,如果按照上面的展开过程,对Feb(m)展开到第n步时的式子是这样的:
Feb(m) = a*Feb(m-n) + b*Feb(m-n-1)
= a*(Feb(m-n-1)+Feb(m-n-2)) + b*Feb(m-n-1)
= (a+b)*Feb(m-n-1) + a*Feb(m-n-2)
这个时候,就可以给出尾递归版本的Feb函数了:
函数 Feb 对给出的 整数 n
返回 Feb1(n,1,0)
可能有人要问,为什么是Feb(n,1,0)不是Feb(n,1,1)呢?这只要验证一下就够了:
Feb1(0,1,0) = 1
Feb1(1,1,0) = Feb1(0,1,1) = 1
Feb1(2,1,0) = Feb1(1,1,1) = Feb1(0,2,1) = 2
......
[ 本帖最后由 earthengine 于 20-8-2009 13:55 编辑 ] |
|