一、生活中的例子:
場景:問路
遞迴
問題:天安門怎麼走?(等待回答)
a:左拐。/ 接下來怎麼走不知道了,你等下,我去問b (a等待b的回答)
b:右拐。/ 接下來怎麼走不知道了,你等下,我去問c (b等待c的回答)
c:左拐。/ 接下來怎麼走不知道了,你等下,我去問d (c等待d的回答)
d:直行就到了。
* 提問者 → a → b → c → d → c → b → a → 提問者
尾遞迴
問題:天安門怎麼走?給你個小紙條,幫我寫在上面(等待回答)
a:寫上 「左拐」。/ 接下來把紙條給b (a空閒了)
b:寫上 「右拐」。/ 接下來把紙條給c (b空閒了)
c:寫上 「左拐」。/ 接下來把紙條給d (c空閒了)
d:寫上 「直行就到了」。(把紙條直接給提問者)
* 提問者 → a → b → c → d → 提問者
二、python**例項
遞迴
**
deffoo(x):
if x == 1:
returnx
else
:
return x * foo(x - 1)
執行過程
===> foo(5)
===> 5 * foo(4)
===> 5 * (4 * foo(3))
===> 5 * (4 * (3 * foo(2)))
===> 5 * (4 * (3 * (2 * foo(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120
尾遞迴
**
deffoo_iter(num, product):
if num == 1:
return
product
return foo_iter(num - 1, num * product)
執行過程
===> foo_iter(5, 1)
===> foo_iter(4, 5)
===> foo_iter(3, 20)
===> foo_iter(2, 60)
===> foo_iter(1, 120)
===> 120
三、總結
1.遞迴(英語:recursion),在數學與電腦科學中,是指在函式的定義中使用函式自身的方法。
2.遞迴函式的優點是定義簡單,邏輯清晰。理論上,所有的遞迴函式都可以寫成迴圈的方式,但迴圈的邏輯不如遞迴清晰。
3.尾遞迴是一種形式,只是用這種形式表達出的概念可以被默寫編譯器優化,尾遞迴的特殊形式決定了這種遞迴**在執行過程中是可以不需要回溯的(通常遞迴都是需要回溯的)。
如果編譯器針對尾遞迴形式的遞迴**作了這種優化,就可能把原本需要線性複雜度棧記憶體空間o(n)的執行過程用常數複雜度的空間o(1)完成。
4.遞迴呼叫可以分為直接遞迴呼叫和間接遞迴呼叫。例如:在函式a(或過程)中直接引用(呼叫)函式a本身就是直接遞迴呼叫。在函式a(或過程)中呼叫另外乙個函式b,而該函式b又引用(呼叫)了函式a就是間接遞迴呼叫。
5.每個遞迴函式都有兩個條件:基線條件和遞迴條件。
6.棧有兩種操作:壓入和彈出。所有函式呼叫都進入呼叫棧。呼叫棧可能很長,這將占用大量的記憶體。
四、參考
什麼是尾遞迴?
求階乘 n def fact n if n 1 return 1return n fact n 1 理論上,所有的遞迴函式都可以寫成迴圈的方式,但迴圈的邏輯不如遞迴清晰 在計算機中,函式呼叫是通過棧 stack 這種資料結構實現的,每當進入乙個函式呼叫,棧就會加一層棧幀,每當函式返回,棧就會減一層棧...
什麼是尾遞迴
遞迴演算法想必大家都已經很熟悉了。遞迴演算法雖然簡單,但是容易導致一些效能問題,於是就有了尾遞迴這種優化演算法。首先我們先看看遞迴演算法的效能問題是在 比如我們有乙個常見的演算法,叫做階乘演算法。f x 1 2 3 x f x 1 cdot2 cdot3 cdots x f x 1 2 3 x他的遞...
什麼是尾遞迴 尾遞迴的底層實現原理
什麼是尾遞迴 尾遞迴的底層實現原理 什麼是尾遞迴?尾遞迴就是函式最後的語句是呼叫函式自身,但呼叫自己的時候,已經 不再需要上乙個函式的環境了。所以並非所有的遞迴都屬於尾遞迴,它需要通過上述的規則來編 寫遞迴 和普通的遞迴相比,尾遞迴即使遞迴呼叫數萬次,它的函式棧也僅為常數,不會出 現stack ov...