【Python學習筆記】遞歸函數

★特殊的一種函數——遞歸函數編程

一般,函數是靠調用其餘函數完成本身的功能的,可是還存在一種調用方式是:函數調用它自身,這樣的函數稱爲遞歸函數
遞歸函數是利用'棧'實現的,遞歸函數的優勢是定義簡單,邏輯清晰,缺點是比較佔用資源,且容易形成棧溢出,甚至致使崩潰編程語言


# 常見的遞歸函數是計算階乘 
def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)
print fact(5)函數

運行效果:
# 理論上,全部的遞歸函數均可以寫成循環的方式,但循環的邏輯不如遞歸清晰。優化

 

# ★★★如非必須,儘可能不用遞歸函數★★★遞歸


#每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出。
# print fact(1000) # 報錯資源

# 解決遞歸調用棧溢出的方法是經過尾遞歸優化,事實上尾遞歸和循環的效果是同樣的,因此,把循環當作是一種特殊的尾遞歸函數也是能夠的。
# 尾遞歸是指,在函數返回的時候,調用自身自己,而且,return語句不能包含表達式。這樣,編譯器或者解釋器就能夠把尾遞歸作優化,使遞歸自己不管調用多少次,都只佔用一個棧幀,不會出現棧溢出的狀況# # 使用尾遞歸優化的計算階乘 編譯器

def fact(n):
    return fact_iter(n, 1)
def fact_iter(num, product):
    if num == 1:
        return product
    return fact_iter(num - 1, num * product)it

運行過程分析:編譯

fact_iter(5, 1)
fact_iter(4, 5)
 fact_iter(3, 20)
 fact_iter(2, 60)
fact_iter(1, 120)
120
# 尾遞歸調用時,若是作了優化,棧不會增加,所以,不管多少次調用也不會致使棧溢出。
# 遺憾的是,大多數編程語言沒有針對尾遞歸作優化,Python解釋器也沒有
# 針對尾遞歸優化的語言能夠經過尾遞歸防止棧溢出。尾遞歸事實上和循環是等價的,沒有循環語句的編程語言只能經過尾遞歸實現循環。循環

相關文章
相關標籤/搜索