尾遞歸優化

  • 今天在看設計模式時提到了尾遞歸優化,于是去網上搜索了一下,又重新讓我認識了遞歸的另一種方式,由此記錄下來.

  • 之前寫過一些算法題,相信大部分人在做算法題時都會避開用遞歸,為什么呢,因為遞歸的調用會讓上一層的方法信息,和一些參數都保存在堆棧中,于是乎如果層數太多,堆棧就會溢出,拋出StackOverflowError這個異常,因為java虛擬機在運行方法時會給每個方法分配一個堆棧空間,方法過多,剩余空間不夠了就會拋那個異常;但是尾遞歸就不太可能會有這個問題,先看一下代碼

    拿斐波那契數列舉例,普通的遞歸會這么寫:

        public static long recu(int n){
            if (n < 2){
                return n;
            }else {
                return recu(n-1)+recu(n-2);
            }
        }
    

    可以看出方法內部的return會不斷保留上一層方法的信息

    再看一下尾遞歸:

        public static long tailRe(int n, long a, long b){
            if (n == 0){
                return a;
            }else {
                return tailRe(n-1, b,a+b);
            }
        }
    

    尾遞歸在返回時不會積累上層方法的信息,因為在調用下一層方法時上層方法已經不起作用了,所以可以直接把上層方法去除掉,節省堆棧空間

    比較一下結果:


    尾遞歸
  • 仔細思考一下,發現尾遞歸的方式就是要滿足在方法返回語句內遞歸方法是返回語句的末尾,且不能有式子出現,因為這樣的話最上層方法需要取得下層方法的結果再來執行本方法,就會產生堆棧空間的大量占用.
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1.什么是遞歸? 程序調用自身的編程技巧稱為遞歸( recursion),就好像你做了一個夢,夢里面夢到夢到自己又...
    夢想怪閱讀 1,028評論 0 2
  • 以遞歸方式思考 遞歸通過靈巧的函數定義,告訴計算機做什么。在函數式編程中,隨處可見遞歸思想的運用。下面給出幾個遞歸...
    JasonDing閱讀 1,464評論 0 1
  • lua程序設計 書中原文 Lua中函數的另一個有趣的特征是可以正確的處理尾調用(proper tail recur...
    人氣小哥閱讀 3,797評論 0 0
  • 什么是尾遞歸 如果一個函數在定義時引用了自身,那么這個函數就是一個遞歸函數。例如我們所熟知的階乘就可以通過遞歸函數...
    Liutos閱讀 814評論 0 1
  • 原文出處: neo1218 一般遞歸與尾遞歸 一般遞歸 執行: 可以看到, 一般遞歸, 每一級遞歸都需要調用函數,...
    PyChina閱讀 2,008評論 1 8