遞迴:也就是在執行過程中自己呼叫自己
乙個過程或
函式在其定義或說明中有直接或間接呼叫自身的一種方法。
它通常把乙個大型複雜的問題層層轉化為乙個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算。它可以用有限的
語句來定義物件的
無限集合
。一般來說,遞迴需要有邊界條件、遞迴前進段和遞迴返回段。
當邊界條件不滿足時,遞迴前進-----遞;當邊界條件滿足時,遞迴返回-----歸。
考慮之前學過的數學方法,遞迴的思想就是歸納法,將問題轉換為與原問題相似的子問題,而子問題又被轉換為子問題的子問題,而且這些問題都有著相同的邏輯,即解決的思路是相同的。
構成遞迴的條件:
子問題與原問題是同樣的事,且更為簡單
不能無限次的呼叫自身,必須有遞迴結束的條件,也就是返回出口
遞迴演算法一般用於解決三類問題:
(1)資料的定義是按遞迴定義的。(fibonacci函式)
(2)問題解法按遞迴演算法實現。
這類問題雖則本身沒有明顯的遞迴結構,但用遞迴求解比迭代求解更簡單,如hanoi問題。
(3)資料的結構形式是按遞迴定義的。
如二叉樹、廣義表等,由於結構本身固有的遞迴特性,則它們的操作可遞迴地描述。
遞迴演算法的一般形式:
void func( mode)
else }
最典型的就是n!演算法
void factorial(int n)
* 輸入任意長度的字串,逆序輸出
思路分析:在此處,是無法用陣列的,因為是任意長度的字串;用動態鍊錶是可以實現儲存任意長度的字串,但是逆序輸出時間複雜度高。此處我們利用遞迴的思想就可以很容易地實現
**如下:
void print()
if(c!='#')
}
然而,遞迴相對於迭代來說,效率低下,
在遞迴呼叫
的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存,增加了系統的開銷。同時,遞迴次數過多容易造成
棧溢位等。如果可以用迭代實現的,就盡量不要用遞迴,但是在某些情況下,用遞迴的優越性就比較明顯,就需要我們用遞迴去實現。
漢諾塔(hanoi)問題:
思路:將n-1個圓盤從x借助z移動到y
將1乙個圓盤從x移動到z
將n-1個圓盤從y借助x移動到z
#include //將 n 個圓盤從 x 借助 y 移動到 z
void move(int n,char x,char y,char z)
else
}int main()
遞迴演算法效率簡析
遞迴最常遇到的問題就是棧溢位 所以在函式遞迴時一定要有合適的終止條件 函式在每次遞迴時,每進行一次新的呼叫,都將建立一批變數,它們將掩蓋遞迴函式前一次呼叫所建立的變數。對於前一節講到的用遞迴函式實現階乘,其實並不是階乘的很好的乙個例子,很多人認為這種做法比較 高階 實則不然,這種做法的效率對於用迴圈...
JAVA基礎 簡析遞迴演算法
概念 遞迴演算法 遞迴演算法是把問題轉化為規模縮小了的同類問題的子問題,然後遞迴呼叫函式 或者過程 來表示函式的解。遞迴函式 乙個過程 或者函式 直接或間接呼叫自己本身,這種過程 或者函式 叫做遞迴函式。特點 遞迴就是在過程或函式裡呼叫自身。在使用遞迴策略時,必須有乙個明確的遞迴結束條件。稱為遞迴出...
簡析窮舉演算法,及其簡單應用
首先我們來看乙個經典的例子 百雞百錢問題 已知 公雞5元乙隻,母雞3元乙隻,小雞一元3只。現用100元錢買了100隻雞。問 公雞母雞小雞各幾隻?請考慮盡可能高效的方法 實際上上面的問題直接用數學的方法是不容易解出來的,因為未知數的個數多餘方程的個數。這時就可以用到窮舉法,列出所有的可能性。分析 假設...