什麼是尾遞迴

2021-10-03 06:10:44 字數 1558 閱讀 6024

遞迴演算法想必大家都已經很熟悉了。遞迴演算法雖然簡單,但是容易導致一些效能問題,於是就有了尾遞迴這種優化演算法。

首先我們先看看遞迴演算法的效能問題是在**?

比如我們有乙個常見的演算法,叫做階乘演算法。

f (x

)=1⋅

2⋅3⋯

⁣x

f(x)=1\cdot2\cdot3\cdots\!x

f(x)=1

⋅2⋅3

⋯x他的遞迴實現是這樣子的

katex parse error: unknown column alignment: 1 at position 15: \beginf(x)=x f(x-1)\…

實現**如下

//c#實現

intfoo

(int x)

return x*

foo(x-1)

;}

#python 實現

deffoo

(x):

if(x==1)

:return

1return x*foo(x-

1)

我們看到每次呼叫foo方法的時候,又會執行一次foo方法。

此時程式會將當前上下文壓棧,計算出下乙個foo的值,然後再出棧和x進行相乘

所以對於foo(3)的呼叫,整個棧的情況是這樣的

katex parse error: unknown column alignment: 1 at position 15: \beginfoo(3)\\3\cdot…

那麼尾遞迴呢?

它是指函式的最後乙個位置(或者動作)是呼叫自身

我們把上面的方法改一下尾遞迴

//c#尾遞迴實現

intfoo

(int x,

int result=1)

return

foo(x-

1,x*result)

;}

#python 尾遞迴實現

deffoo2

(x,result=1)

:if(x==1)

:return result

return foo2(x-

1,result*x)

這裡有兩個需要注意的點

那麼這麼有什麼好處呢?

好處就是「聰明」的編譯器在準備入棧時發現,咦,這裡的遞迴放回值不需要做任何計算,直接返回更上一層就好了。那麼儲存上下文沒有啥好處,不存了!!

所以此時的棧使用情況就會變成

katex parse error: unknown column alignment: 1 at position 15: \beginfoo2(3)\\foo2(…

記憶體占用,顯著減少

不過尾遞迴雖好,但是還是要依賴於各種編譯器的支援。

目前我知道的是python是支援的,探索c#之尾遞迴編譯器優化 - 蘑菇先生 - 文章中表示64位release下會進行尾遞迴優化

本文會經常更新,請閱讀個人部落格原文: ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。

什麼是尾遞迴?

求階乘 n def fact n if n 1 return 1return n fact n 1 理論上,所有的遞迴函式都可以寫成迴圈的方式,但迴圈的邏輯不如遞迴清晰 在計算機中,函式呼叫是通過棧 stack 這種資料結構實現的,每當進入乙個函式呼叫,棧就會加一層棧幀,每當函式返回,棧就會減一層棧...

什麼是 遞迴 和 尾遞迴

一 生活中的例子 場景 問路 遞迴 問題 天安門怎麼走?等待回答 a 左拐。接下來怎麼走不知道了,你等下,我去問b a等待b的回答 b 右拐。接下來怎麼走不知道了,你等下,我去問c b等待c的回答 c 左拐。接下來怎麼走不知道了,你等下,我去問d c等待d的回答 d 直行就到了。提問者 a b c ...

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

什麼是尾遞迴 尾遞迴的底層實現原理 什麼是尾遞迴?尾遞迴就是函式最後的語句是呼叫函式自身,但呼叫自己的時候,已經 不再需要上乙個函式的環境了。所以並非所有的遞迴都屬於尾遞迴,它需要通過上述的規則來編 寫遞迴 和普通的遞迴相比,尾遞迴即使遞迴呼叫數萬次,它的函式棧也僅為常數,不會出 現stack ov...