很多初學者往往對遞歸迷惑不解,也在這上面花了不少的時間。其實教材上的例子很經典,只是它說的有一些唠叨了。初學者會看的頭大的。編程是解決問題的,而現實中很多的問題都是比較簡單的,沒有象漢諾塔那麼復雜。我們也不必追究遞歸到底是怎樣實現的,我們只是要會用遞歸,會用遞歸來為我們解決一些問題,這就行了。
首先來看一個例子:
有一個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%d/n",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<<"Please input the original cattle number:"<
cout<<"Input how many years it past:"<
cout<<"You have "<
}
int cattle(int ct,int n)
{
if(n<4) return (ct); /*停止條件*/
else
return (cattle(ct,n-1)+cattle(ct,n-3)); /*實現遞歸*/
}
怎麼樣,很簡單吧。 會用循環求解嗎?
遞歸在實際的編程中並不常用,但是在某些情況下,它是非常強有力而漂亮的工具。掌握它的原理時會十分有用的。