banner
阿珏酱

阿珏酱

乘上与平常相反的电车,去看看那未曾见过的风景
twitter
github
facebook
bilibili
zhihu
steam_profiles
youtube

什麼是遞迴?

提示:當你看到這個提示的時候,說明當前的文章是由原emlog博客系統搬遷至此的,文章發佈時間已過於久遠,編排和內容不一定完整,還請諒解`

什麼是遞迴?

日期:2017-8-9 阿珏 談天說地 瀏覽:1616 次 評論:5 條

image
圖片來源於網絡

一上來你肯定覺得讀這句話好繞,好吃力。 其實你用遞迴來讀就很簡單了: 遞迴要有一個終點(小鯉魚)
當遞迴尚未達到終點的時候,函數會反覆調用自己。
顯然,輸出"我的小鯉魚"這句話是遞迴終止條件。
那麼寫成代碼就是:


目前我找到的對遞迴最恰當的比喻,就是查詞典。我們使用的詞典,本身就是遞迴,為了解釋一個詞,需要使用更多的詞。當你查一個詞,發現這個詞的解釋中某個詞仍然不懂,於是你開始查這第二個詞,可惜,第二個詞裡仍然有不懂的詞,於是查第三個詞,這樣查下去,直到有一個詞的解釋是你完全能看懂的,那麼遞迴走到了盡頭,然後你開始後退,逐個明白之前查過的每一個詞,最終,你明白了最開始那個詞的意思。。。
image
箭頭線代表程序實際運行步驟。

image
看了樓上很多答案,大多偏重於描述
遞迴 的現象,而沒說明為什麼要用遞迴,遞迴的思想到底是什麼。前陣子剛好看了點東西,試著整理下,如有錯誤之處,請不吝指正。

  • 什麼是遞迴?
1. 定義
Wiki [1]: Recursion 是以自相似的方式重複項目的過程。
具體到計算機中去 [2]:
遞迴 (英語:Recursion),又譯為 迴歸 ,在數學與計算機科學中,是指在函數的定義中使用函數自身的方法。

英文的Recursion從詞源上分析只是"re- (again)" + "curs- (come, happen)" 也就是重複發生,再次重現的意思。而對應的中文翻譯 ”遞迴“ 卻表達了兩個意思:”遞“+”歸“。這兩個意思,正是遞迴思想的精華所在。從這層次上來看,中文翻譯反而更達意。

2. 跟循環的區別

單看上面wiki的定義,貌似跟通常所說的無限死循環很像,他們的區別在哪?
遞迴是靜中有動,有去有回。
循環是動靜如一,有去無回。

舉個例子,給你一把鑰匙,你站在門前面,問你用這把鑰匙能打開幾扇門。

遞迴:你打開面前這扇門,看到屋裡面還有一扇門(這門可能跟前面打開的門一樣大小(靜),也可能門小了些(動)),你走過去,發現手中的鑰匙還可以打開它,你推開門,發現裡面還有一扇門,你繼續打開,。。。, 若干次之後,你打開面前一扇門,發現只有一間屋子,沒有門了。你開始原路返回,每走回一間屋子,你數一次,走到入口的時候,你可以回答出你到底用這鑰匙開了幾扇門。

循環:你打開面前這扇門,看到屋裡面還有一扇門,(這門可能跟前面打開的門一樣大小(靜),也可能門小了些(動)),你走過去,發現手中的鑰匙還可以打開它,你推開門,發現裡面還有一扇門,(前面門如果一樣,這門也是一樣,第二扇門如果相比第一扇門變小了,這扇門也比第二扇門變小了(動靜如一,要麼沒有變化,要麼同樣的變化)),你繼續打開這扇門,。。。,一直這樣走下去。入口處的人始終等不到你回去告訴他答案。

3. 遞迴思想

遞迴就是有去(遞去)有回(歸來)。

具體來說,為什麼可以”有去“?
這要求遞迴的問題需要是可以用同樣的解題思路來回答類似但略有不同的問題(上面例子中的那把鑰匙可以開後面門上的鎖)。

為什麼可以”有回“?
這要求這些問題不斷從大到小,從近及遠的過程中,會有一個終點,一個臨界點,一個baseline,一個你到了那個點就不用再往更小,更遠的地方走下去的點,然後從那個點開始,原路返回到原點。

這篇博文[3]作者歸納為:
遞迴的基本思想是 把規模大的問題轉化為規模小的相似的子問題來解決 。在函數實現時,因為解決大問題的方法和解決小問題的方法往往是同一個方法,所以就產生了函數調用它自身的情況。另外這個解決問題的函數 必須有明顯的結束條件 ,這樣就不會產生無限遞迴的情況了。

4. 什麼時候需要用遞迴?

當有些問題的定義本身就是遞迴形式的時候,最是適合用遞迴來解決。

計算機專業的同學最最熟悉的莫過於” “的定義了[4,5]。還有一些定義,比如階乘,Fibonacci數列[6],等等。用遞迴來解決這些問題,往往幾行代碼就搞定了一些看起來相當”嚇人“的問題。當然,遞迴的性能問題是另一回事,棧的分配,函數調用代價都是在具體工程實踐中要考慮的。但現在只是討論遞迴思想的話,不妨先放下那些,欣賞下遞迴的美。



----以上均來自網友回答

網友評論:

image Railgun 丶無限 2 年前 (2019-03-14)
斐波那契用遞迴是一定會爆棧的,而且非常慢,所有的遞迴都一定有它的非遞迴寫法(當然效率上有的可能快有的就不一定),對於運算的值只依賴於參數的函數如斐波那契,應該採用記憶化思想……
但是遞推有時候真的比遞迴快啊~(逃

image 阿珏 2 年前 (2019-03-14)
@Railgun 丶無限:大學生就是不一樣 [#aru_9]

image Railgun 丶無限 2 年前 (2019-03-14)
@阿珏:可我不僅只是高中還很可能就要沒大學上了啊 Orz

image 阿珏 2 年前 (2019-03-14)
@Railgun 丶無限:這波猜錯了 QAQ

image 天津網站建設 4 年前 (2017-08-15)
文章挺不錯的,謝謝博主。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。