如何解决红宝石的尾递归-这两种实现之间有什么区别?
| 我是Ruby的新手,几天前才开始学习该语言。作为练习,我尝试实现一个简单的快速排序class Sort
def swap(i,j)
@data[i],@data[j] = @data[j],@data[i]
end
def quicksort(lower=0,upper = @data.length - 1)
return nil if lower >= upper
m = lower
i = 0
((lower+1)..upper).each do |i|
swap(++m,i) if @data[i] < @data[lower]
end
swap(m,lower)
quicksort1(lower,m -1)
quicksort1(m+1,upper)
end
end
在说10000个整数上调用quicksort给了我一个堆栈级错误。谷歌搜索之后,我发现Ruby(有点类似)尚不支持尾递归。但是后来我发现了以下代码片段(从这里开始)
def qs(v)
return v if v.nil? or v.length <= 1
less,more = v[1..-1].partition { |i| i < v[0] }
qs(less) + [v[0]] + qs(more)
end
即使使用一百万个整数,运行第二个代码段也可以很好地运行。但是,据我所知,最后有尾巴递归。那我在这里不明白什么呢?
解决方法
您所显示的两种方法都不是尾部递归的(从技术上讲,第一种是尾部递归的:第二种递归调用是尾部调用,但是第一种不是-第二种方法根本不是尾部递归) 。
第一个方法溢出堆栈的原因是第二个方法没有溢出的原因是,第一个方法比第二个方法的递归要深得多(线性而不是对数地),因为存在错误(bug2ѭ只需对to3ѭ应用一元+运算符两次-它实际上对
m
没有任何作用)。
当给定足够大的数组时,两个版本都会溢出(即使ruby确实执行了TCO也是如此),但是如果没有错误,则10000个元素还不够大。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。