初學者看過來:簡單談談 C/C++ 遞迴的思想,實現,以及和迴圈的關係。 (轉)
很多初學者往往對遞迴迷惑不解,也在這上面花了不少的時間。其實教材上的例子很經典,只是它說的有一些嘮叨了。初學者會看的頭大的。是解決問題的,而現實中很多的問題都是比較簡單的,沒有象漢諾塔那麼複雜。我們也不必追究遞迴到底是怎樣實現的,我們只是要會用遞迴,會用遞迴來為我們解決一些問題,這就行了。
首先來看一個例子:
有一個Febonacci序列:
1,1,2,3,5,8,13,,21,34........
它的問題是:求這個序列中的第N個數。
由於它的原形是:f(n)=f(n-1)+f(n-2)
這用遞迴很容易就可以寫出程式碼來,一點都不費事:
int Febc(int n) {
if(n<3) return (1);
else
return (Febc(n-1)+Febc(n-2));
}
噢~~~~~也許你會說遞迴真是太簡單了,簡直就是一個數學模型嘛,呵呵。
其實,遞迴函式的工作過程就是自己自己。有一些問題用遞迴就很容易解決,簡單的你自己都會吃驚。
我們做事情,一般都是從頭開始的,而遞迴卻是從末尾開始的。比如上面的函式吧,當n>3時,它顯然只能求助於n-1,n-2。而(n-1)>2,(n-2)>2時,它們就求助於:(n-1)-1,(n-1)-2;(n-2)-1,(n-2)-2;然後··············直到(n-k)<3,(n-k-1)<3時,函式Febc終於有了返回值1 了,它再從頭開始計算,然後一直算到n 為止。
透過上面的例子,我們知道遞迴一定要有一個停止的條件,否則遞迴就不知道停止了。在上面的例子中, if(n<3) return (1); 就是停止的條件。
然而,使用遞迴的代價是十分巨大的:它會消耗大量的!!遞迴迴圈時它用的是堆疊,而堆疊的資源是十分有限的。上面的例子你只能用一個很小的n值。如果n=20,即Febc(20)的話,它將呼叫Febc(n)函式10000多次!!!而上面一個例子用迴圈也是十分容易寫的:
/*using turboc2*/
int febc(int);
main()
{
int n;
scanf("%d",&n);
febc(n);
}
int febc(int n)
{
int a[3],i;
a[0]=a[1]=a[2]=1;
for(i=3;i<=n;i++)
a[i%3]=a[(i+1)%3]+a[(i+2)%3]; /*實現 Febc(i)=Febc(i-1)+Febc(i-2)*/
printf("n%dn",a[n%3]);
}
有興趣者不妨輸入一個較大的n值,然後比較比較這二個函式計算的速度。當然, 如果你使用的n太大的話,遞迴可能發生錯誤。如果當機了可別罵我哦~~~ 我已經提醒過你了 :)
現在我們再來看看一個求從1 加到100的迴圈:
/*turboc2*/
main()
{ int i,n;
for(i=1;i<101;i++)
n+=i; }
這很簡單沒什麼可說的。 但是,你能不能寫出相應的遞迴函式呢?
下面就是遞迴(請注意了,這種做法不推薦!! 我只是為了說明問題才這麼寫的。)
/*using Turboc2*/
int a=0;
int account(int);
main()
{
account(100);
printf("%d",a);
}
int account(int i)
{
if(i==0) return 0; /*停止條件*/
else
a+=account(i-1)+1; /*實現遞迴*/
}
在C/C++的問題中,我曾經回答過這樣的一個問題:
若一頭小母牛,從出生起第四個年頭開始每年生一頭母牛,按此規律,第n年時有多少頭母牛? 請問如何用遞迴涵數求此問題?
先寫出函式:f(n)=f(n-1)+f(n-3)
為什麼f(n)=f(n-1)+f(n-3)呢,請看:
f(n)-f(n-1)=f(n-3)
因為第n年要比n-1年多的牛,都是大於三歲的牛生的小牛,而f(n-3)正是那些在n年大於三歲的牛,然後它們在第n年生下相同數量的小牛。(請用BorlandC++3.1或其他C++)
#include
#include
int cattle(int,int);
void main()
{
int ct,n;
cout< cin>>ct;
cout< cin>>n;
cout< getch();
}
int cattle(int ct,int n)
{
if(n<4) return (ct); /*停止條件*/
else
return (cattle(ct,n-1)+cattle(ct,n-3)); /*實現遞迴*/
}
怎麼樣,很簡單吧。 會用迴圈求解嗎?
遞迴在實際的程式設計中並不常用,但是在某些情況下,它是非常強有力而漂亮的工具。掌握它的原理時會十分有用的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-987822/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 二分法的簡單實現——-遞迴和非遞迴遞迴
- 迴圈佇列C++實現佇列C++
- 淺談C++的class (初學者請看) 高手老手不用浪費網費 (轉)C++
- 詳談javascript和node的事件迴圈JavaScript事件
- 淺談迴圈之硬體級實現
- 通過遞迴實現,單表父子關係資料 或者上下級關係資料的組合遞迴
- 淺談尾遞迴遞迴
- 淺談Javascript單執行緒和事件迴圈JavaScript執行緒事件
- 【C++】翻轉二叉樹(遞迴、非遞迴)C++二叉樹遞迴
- c++遞迴與迭代實現漢諾塔C++遞迴
- 談談IT圈的門檻與學歷的關係以及如何避免青春飯?
- C++ 只能指標迴圈引用簡單測試C++指標
- 【資料結構】迴圈佇列的實現(c++)資料結構佇列C++
- 淺談迴圈依賴
- Python技法:實現簡單的遞迴下降ParserPython遞迴
- 談談 Event Loop(事件迴圈)機制OOP事件
- 付費迴圈——談談《放置奇兵》的付費模式模式
- SQL 遞迴思想SQL遞迴
- 全域性元件實現遞迴樹,避免迴圈引用元件遞迴
- C++中的迴圈結構C++
- 遞迴的簡單應用遞迴
- 淺談js的事件迴圈(Event Loop)JS事件OOP
- 今天來認真談談「樹」的各種遍歷方式以及深入理解下遞迴的思維方式遞迴
- 淺談遞迴演算法遞迴演算法
- 遞迴思想的巧妙理解遞迴
- 遞迴和非遞迴分別實現求n的階乘遞迴
- 斐波那契數列的遞迴和非遞迴實現遞迴
- 原:八皇后問題的遞迴和非遞迴Java實現遞迴Java
- 為什麼你學不會遞迴?告別遞迴,談談我的一些經驗遞迴
- strcmp的遞迴實現遞迴
- C++物件導向程式設計——遞迴實現字串的反序C++物件程式設計遞迴字串
- 玩家是如何在遊戲中沉迷的? 談談有限迴圈和返回觸發遊戲
- JavaScript之遞迴的簡單使用JavaScript遞迴
- 簡單的加減乘除(遞迴)遞迴
- while迴圈以及do while迴圈While
- 關於樹型結構資料遞迴查詢,轉非遞迴查詢的實現遞迴
- 簡單實現Android中的訊息迴圈機制Android
- 單向迴圈連結串列的實現