簡書 賈小強
轉載請注明原創出處,謝謝!
什么是尾遞歸
遞歸 的本質是某個方法調用了自身,每次調用將問題變小,直到能夠直接解決
尾遞歸 是遞歸中的一種特殊形式,其要求為:某個方法調用自身這件事,一定是該方法做的最后一件事
1,當有需要返回值的時候會是return f(n),沒有返回的話就直接是f(n)了
2,return f(n)外不能加其他東西,否則就不是最后一件事了
比如有返回值的,你不能乘個常數n 如 return n*f(n);甚至是 f(n)+f(n-1)
//沒有使用尾遞歸的形式
def recsum(x):
if x == 1:
return x
else:
return x + recsum(x - 1)
//使用尾遞歸的形式
def tailrecsum(x, running_total=0):
if x == 0:
return running_total
else:
return tailrecsum(x - 1, running_total + x)
尾遞歸優化的原因
1,因為在遞歸調用自身的時候,這一層函數已經沒有要做的事情了,雖然被遞歸調用的函數是在當前的函數里,但是他們之間的關系已經在傳參的時候了斷了,也就是這一層函數的所有變量什么的都不會再被用到了,所以當前函數雖然沒有執行完,不能彈出棧,但它確實已經可以出棧了
2,正因為調用的是自身,所以需要的存儲空間是一毛一樣的,那干脆重新刷新這些空間給下一層利用就好了,不用銷毀再另開空間
Java沒有尾遞歸優化的原因
As explained by Brian Goetz (Java Language Architect at Oracle) :
in jdk classes [...] there are a number of security sensitive methods that rely on counting stack frames between jdk library code and calling code to figure out who's calling them.
Anything that changed the number of frames on the stack would break this and would cause an error. He admits this was a stupid reason, and so the JDK developers have since replaced this mechanism.
He further then mentions that it's not a priority, but that tail recursion
will eventually get done.
N.B. This applies to HotSpot and the OpenJDK, other VMs may vary.
Happy learning !!