初學者看過來:簡單談談 C/C++ 遞迴的思想,實現,以及和迴圈的關係。 (轉)

worldblog發表於2007-12-04
初學者看過來:簡單談談 C/C++ 遞迴的思想,實現,以及和迴圈的關係。 (轉)[@more@]

 

  很多初學者往往對遞迴迷惑不解,也在這上面花了不少的時間。其實教材上的例子很經典,只是它說的有一些嘮叨了。初學者會看的頭大的。是解決問題的,而現實中很多的問題都是比較簡單的,沒有象漢諾塔那麼複雜。我們也不必追究遞迴到底是怎樣實現的,我們只是要會用遞迴,會用遞迴來為我們解決一些問題,這就行了。

  首先來看一個例子:

有一個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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章