動畫:這一次用動畫搞懂遞歸!

遞歸這玩意兒,尤其是對於初學者,在數據結構和算法中歸爲“玄學”一類。咳咳,如果今天鹿哥能把這玄學的玩意兒講明白,豈不是要上天。同樣講不明白的後果,鹿哥將會被後臺的石錘大隊石錘…

在這裏插入圖片描述

其實不學遞歸也沒啥,但是學到後邊會發現,什麼 0-1 揹包問題(動態規劃內容,也可以用遞歸解決)、深度廣度優先遍歷、八皇后問題,回溯算法等,反正各種內容都會涉及到遞歸。所以,今天放句狠話,必須搞它,搞的它明明白白的。

在這裏插入圖片描述

(此篇調動全身的細胞去講明白遞歸,雖然看起來很簡單,但是給一個沒有接觸過遞歸的人講懂很難)


什麼是遞歸

對於玄學,絕不能用正常思維去搞它,那絕對是搞不它的。既然是玄學,那我們就採用玄學思維去理解和分析遞歸。

爲啥叫它玄學?不是有多難,而是有些人,一看就明白,一用就是精髓。而有些人呢,比如我,一開始咋看咋覺得這東西就像是“黑洞”,遞進去,就歸不出來了。

在這裏插入圖片描述

劃重點,遞歸,必須有遞有歸才叫遞歸。爲了能夠形象的代表一下,先了解一下遞歸的操作,小二,上動畫。

在這裏插入圖片描述

從一個簡單問題入手

要想搞懂遞歸,不能直接上手複雜的遞歸問題,而是先從一個簡單的問題入手。

我們就拿排隊打飯的例子,如果鹿哥要去餐廳,人太多,不得不去排隊,但是此時我想知道自己是隊伍中第幾個,由於隊伍太長,我看不到隊伍的第一個人,自然而然沒法一個個的數。

那麼玄學遞歸排上用場了,我會讓我前邊的人依次問自己是當前第幾個人,然後依次類推,直到問到第一個人,那麼這個過程是“遞”的過程。

在這裏插入圖片描述

第一個人不耐煩吼了一聲,你眼X啊,沒看到我是第一個人,正在打飯嗎?

這個人吼了一聲,這個就是所謂的終止條件,也就是遞的終點。

在這裏插入圖片描述

此時,鹿哥肚子咕咕的叫了兩聲,當然,我現在還不知道自己是隊伍第幾個。此時隊伍中的第二個人知道位置了,然後告訴第三個人,第三個人告訴第四個人…

在這裏插入圖片描述

最後,我前一個人告訴他目前在隊伍中是第幾個,那麼鹿哥就知道自己此時的位置。很容易理解,這個過程就是“歸”的過程。


遇到的問題

由此看來,鹿哥的道德素質沒的說,從來不插隊,而且還能理解遞歸,一個字“騷”,兩個字“真騷”。

在這裏插入圖片描述

這時候有人要說了,這個過程俺早就理解了,但是對於有些遞歸問題和代碼,腦子裏總是想不明白層層嵌套的過程,而且總是想着想着就遞進去,歸不出來了,哎,我這腦子,是不是很笨呢。

鹿哥告訴大家,其實不用擔心,凡事都要有個過程,要有個思想轉化的過程,要用心去感受,感受它的撫摸,感受它帶給你的快感。

這時候,很多人的告訴你的解決辦法是,不要去想這個過程,要去尋找終止條件和遞推公式,然後按照套路寫出代碼。

嗯~ 對~,鹿哥認爲上邊確實說的沒錯,但是這類玄學玩家並沒有搞明白爲什麼初學者往往去想這個過程,進入這個過程圈套呢?

鹿哥想了一想,結合自己學習遞歸的經驗,越是想不明白,就越想弄明白遞歸過程,這不叫刨根問底,這叫“騷氣風發”。

假如我們搞明白一次遞歸的整個過程,那麼以後遇到其他的遞歸就無需去想這個過程了,因爲其他的遞歸幾乎一樣的套路,我們心理上接受之後,假裝自己知道了所有的遞歸過程,以後再遇遞歸,不再去想這個過程,而是直接按照公式套用不就 OK 了嗎?

鹿哥,你說起來容易,你能用什麼方法讓我們這些剛接觸過遞歸的人明白這個遞歸過程。其實這件事困擾了鹿哥好久,作爲一個爲被稱爲寫文風騷,動畫風騷的鹿哥,今天斗膽嘗試一下,看懂了就給我瘋狂在底部點贊,把鹿哥按到地上摩擦,這才能凸顯出鹿哥的 Sao 氣。


用動畫理解遞歸

繼續拿排隊那個例子,我們已經知道了終止條件和層與層之間的關係。

終止條件爲:f(1) = 1,也就是第一個人知道自己的位置的。然後層與層之間的關係爲 + 1 的關係,也就是說求第 n 個人在隊伍中的位置 f(n),那麼就問一下前一個人,也就是 n-1 在隊伍當中的位置 f(n-1) 加上 1,也就是 f(n-1) + 1。

有點繞口,咱們看完整的實現代碼:

在這裏插入圖片描述

如果你還是有點懵逼的話,還是不能理解整個程序的運作,小二,上圖解和動畫。

在這裏插入圖片描述
上邊的動畫是我們人腦的理解,而下邊的動畫纔是程序真正的調用過程。

每個顏色的方塊代表的是該每一層遞歸的函數,而程序是自上而下執行滴,也就是下邊這種形式。

在這裏插入圖片描述

如果你理解函數的執行過程就是入棧過程的話,其實遞歸就是不斷入棧的過程,然後最裏層的函數執行完畢,然後函數依次出棧。

如果你寥寥草草的閱讀完畢,並沒有感覺看懂遞歸過程,這可真不怪你們鹿哥了,你鹿哥已經盡力用動畫去還原程序遞歸過程和大腦的遞歸過程了。


光說不練假把式

如果上邊你能夠喫透,那麼下面的那些題型以及以後的文章所提到的各種有關遞歸的過程,真的不在話下。有時候只是換了一個角度理解,換了一個角度理解,換了一個角度理解,鹿哥重要的 Sao 話說三遍。

再來一個叫什麼斐波那契數列的那傢伙,槓槓滴。找規律 0、1、1、2、3、5、8、13、21… 沒錯,除了第一第二個,剩餘的數據都是前兩個數據之和,那麼求第 n 個數據是多少?

其實這個問題對你來說已經小 K 死了,就是換了個模樣,前兩個數不就是換了一個問法,也就是上邊排隊的時候,鹿哥前邊兩個人嘛?一個叫 n-1 一個叫 n-2,終止條件變成兩個窗口,同時給第一個人和第二個人打飯,也就是 f(1) = 0,f(2) = 1。

直接出結果,代碼如下:

在這裏插入圖片描述

我會變形,專門誤導你

其實相同的遞歸公式確有不同的理解方式,這你敢信?難道這就是遞歸歸爲玄學的地方,不信你看,下面說來就來了。

一個蛤蟆二條腿,兩隻蛤蟆四條腿 三隻…,不對,應該是蛤蟆一次可能跳上一個臺階,也有可能一次跳兩個臺階,那麼 n 個臺階,有幾種跳躍方式呢?

這個咋就和上邊排隊不一樣了呢?嗯,不知道如何理解和下手。

其實這個數蛤蟆腿,不對,這個蛤蟆跳臺階的問題只不過換了一種思考方式,我們來看這種思想是如何繞暈我們的。

一個臺階,只存在一種可能,那就是讓蛤蟆跳一次。二個臺階,有兩種可能,那就是讓蛤蟆一次只跳一個臺階,或者一次性挑兩個臺階。那麼三個臺階,你自己數數去吧,我就不囉嗦了。

那麼 n 個臺階有幾次可能,這樣一個個數太費勁,我們換種思想,也就是遞歸的思想。我們將蛤蟆跳臺階分爲 m 次跳上去。第一次跳,有兩種方式,那就是要麼一次性跳一個臺階,剩餘的 n-1 個臺階我先不管。或者第一次跳兩個臺階,剩餘的 n-2 個臺階我暫時不管。

如果 f(n) = m,也就是當前有多少次跳法。我想把上邊的兩種相加,剩餘的暫時先不管,也就是 f(n) = f(n-1) + f(n-2)。

那麼神奇的一刻就要來了,n 個臺階,我決定了第一次只跳一個臺階之後,那剩餘 n-1 個臺階的每個臺階就會面臨同樣的選擇。如果我決定了第一次只跳 2 個臺階之後,那麼剩餘的 n-2 個臺階的每個臺階也會面臨同樣的選擇。

蛤蟆的的第一次就這樣交在鹿哥手中,要麼你第一次跳一個,要麼跳兩個,想一步登天喫天鵝肉,沒門。剩餘的 f(n-1) 和 f(n-2) 面臨同樣的選擇呀。

只要把 f(n - 1) + f(n - 2) 相加,就是 n 個臺階有幾種跳法了。我知道,大部分初學者還是不理解這個思想,圖解來一波。

在這裏插入圖片描述

思考總結

你會發現蛤蟆跳臺階的問題,得出來的遞推公式竟然和斐波那契數列的遞推公式竟然相同,但是終止條件不同的。

這時你必須像鹿哥一樣陷入玄學遞歸的大思考,同樣的一個遞推公式,竟然有兩種思想,感覺這世界還有這麼 TM 神奇的事情,這兩者讓我陷入了對人生的大思考…

今天的遞歸基礎理解內容就到這裏了,後邊還會繼續分享更復雜的遞歸,雖然表面上假裝讓它複雜,但是就是換湯不換藥,比如深度廣度優先遍歷,八皇后問題,回溯算法等,都是和今天分享的八九不離十,最重要的是多去思考和感悟以及總結,這個過程值的你去做。

騷氣的鹿哥寫文不易啊,不要手下留贊,因爲這將決定下一篇你鹿哥輸出的動力,點了贊你就是鹿哥的人,鹿哥今後罩着你。

在這裏插入圖片描述
1、老鐵們,關注我的原創微信公衆號 「 小鹿動畫學編程」,專注於數據結構和算法,網絡原理,計算機基礎、Web 大前端等,歡迎來鹿哥公衆號搞事情。一天一篇動畫家屬技術搞定你。。

2、給俺點個讚唄,可以讓更多的人看到這篇文章,順便激勵下我,就這麼臉皮厚!

❤️ 不要忘記留下你學習的腳印 [點贊 + 收藏 + 評論]

文章寫了了好幾個小時,不妨點贊支持一下。嘻嘻,你不點贊說明你很自私,你怕那麼好的文章讓別人也看到。開個小小玩笑。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章