您的位置:首页 > 其它

尾递归讨论--待完结

2016-04-13 09:29 113 查看
按: 本文书于半年前,近日清理电脑内容,暂列于此。

尾递归优化

每一次递归调用都会在栈区引入新的一层方法栈。如递归求解fabonacci值。可写如下实现:

def fabonacci(n)

return n if n < 2

return fabonacci(n-1) + fabonacci(n-2)

end

这里调用一次fabonacci(n)将导致fabonacci(n-1)、fabonacci(n-2) 入栈。fabonacci(n-1)也会将fabonacci(n-2)、fabonacci(n-3)入栈。这样,递归次数将以指数增长

➜ expace ruby -rprofile fabonacci_tail.rb 1

% cumulative self self total

time seconds seconds calls ms/call ms/call name

0.00 0.00 0.00 2 0.00 0.00 Object#fab

0.00 0.00 0.00 1 0.00 0.00 Object#fab_recur

➜ expace ruby -rprofile fabonacci_tail.rb 2

% cumulative self self total

time seconds seconds calls ms/call ms/call name

0.00 0.00 0.00 3 0.00 0.00 Object#fab

0.00 0.00 0.00 3 0.00 0.00 Object#fab_recur

➜ expace ruby -rprofile fabonacci_tail.rb 4

% cumulative self self total

time seconds seconds calls ms/call ms/call name

0.00 0.00 0.00 5 0.00 0.00 Object#fab

0.00 0.00 0.00 9 0.00 0.00 Object#fab_recur

➜ expace ruby -rprofile fabonacci_tail.rb 8

% cumulative self self total

time seconds seconds calls ms/call ms/call name

0.00 0.00 0.00 9 0.00 0.00 Object#fab

0.00 0.00 0.00 67 0.00 0.00 Object#fab_recur

➜ expace ruby -rprofile fabonacci_tail.rb 16

% cumulative self self total

time seconds seconds calls ms/call ms/call name

87.50 0.07 0.07 3193 0.02 0.24 Object#fab_recur

0.00 0.08 0.00 17 0.00 0.00 Object#fab

➜ expace ruby -rprofile fabonacci_tail.rb 24  1 % cumulative self self total

time seconds seconds calls ms/call ms/call name

84.18 3.14 3.14 150049 0.02 0.41 Object#fab_recur

0.00 3.73 0.00 25 0.00 2.80 Object#fab

以上是求fabonacci(n)时的递归次数统计。 为什么没有fab(32),原因是fab(32)在本环境下profile要很长时间。故未列出。

由此可见,尾递归优化十分有效。

附 测试源代码

➜ expace cat fabonacci_tail.rb

def fab(n, a, b)

return a if n < 1

fab(n-1, b, a+b)

end

def fab_recur(n)

return n if n < 2

fab_recur(n-1) + fab_recur(n-2)

end

n=ARGV[0].to_i

fab(n,0,1)

fab_recur(n)

尝试使用了fact尾递归,似乎没有效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: