什麼是尾遞歸/尾遞歸的底層實現原理

什麼是尾遞歸/尾遞歸的底層實現原理

    什麼是尾遞歸?尾遞歸就是函數最後的語句是調用函數自身,但調用自己的時候,已經
不再需要上一個函數的環境了。所以並非所有的遞歸都屬於尾遞歸,它需要通過上述的規則來編
寫遞歸代碼。和普通的遞歸相比,尾遞歸即使遞歸調用數萬次,它的函數棧也僅爲常數,不會出
現Stack Overflow異常。

    遞歸和循環的區別?從jvm的角度來說,遞歸每增加一層,使用的棧內存都會增加一個棧幀,
也就是說遞歸是以消耗內存爲代價來換取執行速度。循環佔用的棧幀是固定的,不會隨着循環次
數的增加而增加,但是執行速度會隨着循環次數的增加而增加。

    尾遞歸的優勢?尾遞歸很好的融合了遞歸和循環的優點,尾遞歸既融合了遞歸速度快的優點,
又融合了循環佔用內存小的特點。

    尾遞歸佔用的棧幀爲什麼不會隨着遞歸深度的增加而增加呢?這就要搞清楚尾遞歸的實現原
理了。尾遞歸實際上是利用了計算機科學的尾調用,什麼是尾調用呢?尾調用指的是一個函數最
後一個操作是函數調用。這句話需要好好回味,感興趣的朋友可以百度一下,務必先搞清楚什麼
是尾調用。好,回到尾遞歸上來,如果一個函數最後一個操作是調用函數本身,那麼這就是尾遞
歸。

    普通遞歸與尾遞歸的本質區別。尾遞歸在當前棧幀執行完之後,不需要再保留當前棧幀,而
是帶着當前棧幀的結果,進入到下一棧幀。這裏有興趣的朋友可以研究一下棧幀的生命週期。普
通的遞歸則不同了,普通的遞歸由於當前棧幀還沒有執行完,就要調用其他棧幀了,當前棧幀不
能退出,所以普通的遞歸佔有的棧幀會隨着遞歸層次的增加而增加。這就是普通遞歸和尾遞歸的
本質區別。

    尾遞歸算法的價值。尾遞歸算法巧妙的運用了計算機的尾調用,充分利用了計算機硬件的設
計原理,能夠使程序更高效的運行。但是並非所有的遞歸都可以改寫成尾遞歸,所以實際使用時
還是要具體問題具體分析。在平時的開發工作中,儘量堅持這樣一個原則:能用尾遞歸解決的問
題,堅決不要使用普通的遞歸。

    文章最後解釋一下普通遞歸和尾遞歸。尾遞歸其實是一種特殊的遞歸。本質上也是遞歸,
所以本文中的普通遞歸準確的表述應該是非尾遞歸的遞歸。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章