尾递归讨论--待完结

按: 本文书于半年前,近日清理电脑内容,暂列于此。

尾递归优化


每一次递归调用都会在栈区引入新的一层方法栈。如递归求解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尾递归,似乎没有效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值