漫談遞迴 遞迴的思想 用歸納法來理解遞迴

2021-08-09 20:10:53 字數 2681 閱讀 1994

為什麼要用遞迴

程式設計裡面估計最讓人摸不著頭腦的基本演算法就是遞迴了。很多時候我們看明白乙個複雜的遞迴都有點費時間,尤其對模型所描述的問題概念不清的時候,想要自己設計乙個遞迴那麼就更是有難度了。

用歸納法來理解遞迴

數學都不差的我們,第一反應就是遞迴在數學上的模型是什麼。畢竟我們對於問題進行數學建模比起**建模拿手多了。 (當然如果對於問題很清楚的人也可以直接簡歷遞迴模型了,運用數模做中介的是針對對於那些問題還不是很清楚的人)

自己觀察遞迴,我們會發現,遞迴的數學模型其實就是歸納法,這個在高中的數列裡面是最常用的了。回憶一下歸納法。

歸納法適用於想解決乙個問題轉化為解決他的子問題,而他的子問題又變成子問題的子問題,而且我們發現這些問題其實都是乙個模型,也就是說存在相同的邏輯歸納處理項。當然有乙個是例外的,也就是遞迴結束的哪乙個處理方法不適用於我們的歸納處理項,當然也不能適用,否則我們就無窮遞迴了。這裡又引出了乙個歸納終結點以及直接求解的表示式。如果運用列表來形容歸納法就是:

這樣其實就結束了,遞迴也就出來了。遞迴演算法的一般形式:

01voidfunc( mode)

02

07else

08

13}

最典型的就是n!演算法,這個最具有說服力。理解了遞迴的思想以及使用場景,基本就能自己設計了,當然要想和其他演算法結合起來使用,還需要不斷實踐與總結了。

01#include "stdio.h"

02#include "math.h"

03

04intmain(void)

05

14

15// 遞迴計算過程

16intfactorial(n)

20returnn * factorial(n-1);

21}

求階乘的遞迴比較簡單,這裡就不展開了。

再來兩個遞迴的例子

返回乙個二叉樹的深度:

1intdepth(tree t)

8}

判斷乙個二叉樹是否平衡:

1intisb(tree t)

第乙個演算法還是比較好理解的,但第二個就不那麼好理解了。第乙個演算法的思想是:如果這個樹是空,則返回0;否則先求左邊樹的深度,再求右邊數的深度,然後對這兩個值進行比較哪個大就取哪個值+1。而第二個演算法,首先應該明白isb函式的功能,它對於空樹返回0,對於平衡樹返回樹的深度,對於不平衡樹返回-1。明白了函式的功能再看**就明白多了,只要有乙個函式返回了-1,則整個函式就會返回-1。(具體過程只要認真看下就明白了)

對於遞迴,最好的理解方式便是從函式的功能意義的層面來理解。了解乙個問題如何被分解為它的子問題,這樣對於遞迴函式**也就理解了。這裡有乙個誤區(我也曾深陷其中),就是通過分析堆疊,分析乙個乙個函式的呼叫過程、輸出結果來分析遞迴的演算法。這是十分要不得的,這樣只會把自己弄暈,其實遞迴本質上也是函式的呼叫,呼叫的函式是自己或者不是自己其實沒什麼區別。在函式呼叫時總會把一些臨時資訊儲存到堆疊,堆疊只是為了函式能正確的返回,僅此而已。我們只要知道遞迴會導致大量的函式呼叫,大量的堆疊操作就可以了。

小結遞迴的基本思想是把規模大的問題轉化為規模小的相似的子問題來解決。在函式實現時,因為解決大問題的方法和解決小問題的方法往往是同乙個方法,所以就產生了函式呼叫它自身的情況。另外這個解決問題的函式必須有明顯的結束條件,這樣就不會產生無限遞迴的情況了。

延伸閱讀

此文章所在專題列表如下:

漫談遞迴:遞迴的思想

漫談遞迴:遞迴需要滿足的兩個條件

漫談遞迴:字串回文現象的遞迴判斷

漫談遞迴:二分查詢演算法的遞迴實現

漫談遞迴:遞迴的效率問題

漫談遞迴:遞迴與迴圈

漫談遞迴:迴圈與迭代是一回事嗎?

遞迴計算過程與迭代計算過程

漫談遞迴:從斐波那契開始了解尾遞迴

漫談遞迴:尾遞迴與cps

漫談遞迴:補充一些continuation的知識

漫談遞迴:php裡的尾遞迴及其優化

漫談遞迴:從彙編看尾遞迴的優化

我喜歡我的收藏夾

不打個分嗎?

如果你認為這篇文章值得更多人閱讀,歡迎使用下面的分享功能。

基於遞迴的技術 歸納法

selectionsortrec input a 1.n output 非降序 a 1.n 1.sort 1 過程 sort output 非降序 a 1.n 1.sort n 過程 sort i if i 1 then x a i sort i 1 j j 1 while j 0 a j x a ...

漫談遞迴 遞迴的思想

為什麼要用遞迴 程式設計裡面估計最讓人摸不著頭腦的基本演算法就是遞迴了。很多時候我們看明白乙個複雜的遞迴都有點費時間,尤其對模型所描述的問題概念不清的時候,想要自己設計乙個遞迴那麼就更是有難度了。用歸納法來理解遞迴 數學都不差的我們,第一反應就是遞迴在數學上的模型是什麼。畢竟我們對於問題進行數學建模...

Dijkstra演算法的思想和數學歸納法

數學歸納法是一種藝術,玩過多公尺諾骨牌的都知道,要使得任意數量的所有牌全部翻掉需要兩個條件而且只需要兩個條件,乙個就是任意兩張牌間隔足夠近,另乙個條件就是你必須推到第一張牌,就是這麼簡單。於是如果你往這個遊戲靠攏你會發現,牌的倒掉和牌的數量以及牌上的內容沒有任何關係,那麼任何可以歸結到這個遊戲的數學...