日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅谈递归与尾递归

發布時間:2024/4/17 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈递归与尾递归 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? 一個對自己本身的遞歸尾調用,就叫做尾遞歸。這里尾調用的“尾”字,是指運行時需要執行的最后一個動作。不是簡單的語法字面上的最后一個語句。 尾遞歸實際執行的是迭代的計算過程。線性遞歸函數必須滿足以下兩個基本屬性:

? ? ?*必須清晰無誤地解決基的情況。

? ? ?*每一個遞歸的調用,必須包含更小的參數值。

? ? ? 而尾遞歸則不必滿足這兩個條件。

? ? ? 普通的線性遞歸比尾遞歸更加消耗資源, 在實現上說, 每次重復的過程調用都使得調用鏈條不斷加長. 系統不得不使用棧進行數據保存和恢復.而尾遞歸就不存在這樣的問題, 因為它的狀態完全由函數的參數保存. 并且,由于尾遞歸的函數調用出現在調用者函數的尾部,因為是尾部,所以根本沒有必要去保存任何局部變量。直接讓被調用的函數返回時越過調用者,返回到調用者的調用者去。尾調用優化不是什么很復雜的優化,實際上幾乎所有的現代的高級語言編譯器都支持尾調用這個很基本的優化。 實現層面上,只需要把匯編代碼call改成jmp, 并放棄所有局部變量壓棧處理,就可以了。這樣一來,堆棧根本就沒有被占用,每次調用都是重新使用調用者的堆棧。盡管尾遞歸比遞歸高效,但并非所有的遞歸算法都可以轉成尾遞歸的,因為尾遞歸本質上執行的是迭代的計算過程。這與并非所有的遞歸算法都可以轉成迭代算法的原因是一樣的。

? ? ? 例子:java實現

public class Recursion {
public static void main(String[] args) {
System.out.println(factorial(6));
System.out.println(factorial2(6, 1));
System.out.println(reciprocal(3.0));
System.out.println(reciprocal2(3.0, 1));
}

// 遞歸 求 N 的階乘
private static int factorial(int n) {
if (n == 0 || n == 1) {
return 1;
} else if (n < 0) {
return 0;
} else {
return n * factorial(n - 1);
}
}

// 尾遞歸 求 N 的階乘
private static int factorial2(int n, int result) {
if (n == 0 || n == 1) {
return result;
} else if (n < 0) {
return 0;
} else {
return factorial2(n - 1, result * n);
}
}

// 遞歸求 1+1/2+1/3+1/4+......+n/1
private static double reciprocal(double n) {
if (n < 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
return 1.0 / n + reciprocal(n - 1);
}
}

// 尾遞歸 求 1+1/2+1/3+1/4+......+1/n
private static double reciprocal2(double n, double result) {
if (n < 0) {
return 0;
} else if (n == 1) {

return result;
} else {
return reciprocal2(n - 1, result + 1.0 / n);
}
}
}

轉載于:https://www.cnblogs.com/lsc183/archive/2012/12/24/weidigui.html

總結

以上是生活随笔為你收集整理的浅谈递归与尾递归的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。