邏輯是數學的少年時代,數學是邏輯的成年時代。「遞迴」這是在程式、演算法設計中的基礎和重中之重。當初理解這一點我也花費了不少時間,對於初學者來說,如何生動形象的展現著一過程,成了理解這一思想的關鍵。——羅素
這篇博文的來由,源於同學問我的乙個問題:
我一看啊,這波,這波是明顯的遞迴啊!!
程式呼叫自身的程式設計技巧稱為遞迴( recursion)。遞迴做為一種演算法在程式語言中廣泛應用。 乙個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把乙個大型複雜的問題層層轉化為乙個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大地減少了程式的**量。遞迴的能力在於用有限的語句來定義物件的無限集合。一般來說,遞迴需要有邊界條件、遞迴前進段和遞迴返回段。當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回。我想這,這麼生硬的解釋,還是別麻煩人家了吧,於是這個解釋就鴿了好幾天
某個摸魚的晚上,我突然想到了乙個解釋遞迴生動形象的例子,那就是:
俄羅斯套娃!!
那麼,如何用俄羅斯套娃的思想去理解遞迴思想呢?
又是眾所周知,遞迴其實就是程式呼叫自身,這不就好像是,在自己肚子裡面裝了乙個自己麼?
不過,我們開這個套娃的方式,得遵循以下規則;
先把套娃的上半部分拿走(執行呼叫自身的函式上邊的**);
繼續拿上半部分,直到拿出了乙個不能在開的娃(遞迴到底);
看看這個不能再套娃的娃(完整的執行這個最「深」的函式);
在依次拿出所有套娃的下半身(自底向上執行所有遞迴函式的下半部分)。
我們先看這個求樹的深度的**:
int treedepth(bt *t)
}
我就畫個圖來看看吧
假設有這麼一顆樹,bt是函式中指標*t所在位置
我們執行這一段**
int treedepth(bt *t)
}
這裡我們發現,可以一直走右子樹走下去,參考上一步的操作,以此類推,我們得到下圖
再繼續推下去,整個程式的返回值就一目了然了
這裡還是要再提一下深度優先搜尋(dfs),眾所周知深搜的最基本技巧就是遞迴。
ps:雖然深搜也可以用棧實現,不過遞迴就是程式自己調出棧來儲存資料,差別不大。樹是特殊的圖,樹的遍歷也是圖的遍歷,這種按照深度一口氣遍歷下來的方式,就是我們所謂的dfs,再樹基礎的學習過程中,我們也可以體會到很多圖的性質
希望我的拋磚引玉能引起更多的思考
求解二叉樹的高度(遞迴 非遞迴)
遞迴方式 遞迴方式的求解過程很簡單,只需要將問題分解。首先,遞迴出口是什麼?毫無疑問,當樹節點為空時,我們就可以結束遞迴了。那麼當前樹的高度和其左子樹及右子樹的關係是什麼呢?樹的高度,定義為從根節點到葉子節點的最長路徑 因此當前樹深應該是自身節點所佔的一層高度加上左右子樹中深的高度。因此,有一下遞迴...
四 二叉樹的映象遞迴非遞迴求解
先序遍歷樹的每乙個結點,若遍歷到的結點有子結點。則交換它的兩個子結點。1.遞迴求解 voidmirrorecursively binarytreenode pnode 2.非遞迴求解 借助棧 借助於棧,先交換兩棵子樹,再求完一棵子樹的映象後在求還有一棵子樹的映象 縱向,深度優先 voidmirror...
二叉樹深度求解(遞迴,非遞迴)
遞迴實現基本思想 為了求得樹的深度,可以先求左右子樹的深度,取二者較大者加1即是樹的深度,遞迴返回的條件是若節點為空,返回0 演算法 1 intfindtreedeep bintree bt 8return deep 9 非遞迴實現基本思想 受後續遍歷二叉樹思想的啟發,想到可以利用後續遍歷的方法來求...