C++递归用法
轉(zhuǎn)自:http://bbs.ikaka.com/showtopic-664019.aspx
簡(jiǎn)單談?wù)凜++ 遞歸的思想實(shí)現(xiàn)以及和循環(huán)的關(guān)系
很多初學(xué)者往往對(duì)遞歸迷惑不解,也在這上面花了不少的時(shí)間。其實(shí)教材上的例子很經(jīng)典,只是它說的有一些嘮叨了。初學(xué)者會(huì)看的頭大的。編程是解決問題的,而現(xiàn)實(shí)中很多的問題都是比較簡(jiǎn)單的,沒有象漢諾塔那么復(fù)雜。我們也不必追究遞歸到底是怎樣實(shí)現(xiàn)的,我們只是要會(huì)用遞歸,會(huì)用遞歸來為我們解決一些問題,這就行了。
首先來看一個(gè)例子:
有一個(gè)Febonacci序列:
1,1,2,3,5,8,13,,21,34........
它的問題是:求這個(gè)序列中的第N個(gè)數(shù)。
由于它的函數(shù)原形是:f(N)=f(n-1)+f(n-2)
這用遞歸很容易就可以寫出代碼來,一點(diǎn)都不費(fèi)事:
int Febc(int n) {
if(n<3) return (1);
else
return (Febc(n-1)+Febc(n-2));
}
噢~~~~~也許你會(huì)說遞歸真是太簡(jiǎn)單了,簡(jiǎn)直就是一個(gè)數(shù)學(xué)模型嘛,呵呵。
其實(shí),遞歸函數(shù)的工作過程就是自己調(diào)用自己。有一些問題用遞歸就很容易解決,簡(jiǎn)單的你自己都會(huì)吃驚。
我們做事情,一般都是從頭開始的,而遞歸卻是從末尾開始的。比如上面的函數(shù)吧,當(dāng)n>3時(shí),它顯然只能求助于n-1,n-2。而(n-1)>2,(n-2)>2時(shí),它們就求助于:(n-1)-1,(n-1)-2;(n-2)-1,(n-2)-2;然后··············直到(n-k)<3,(n-k-1)<3時(shí),函數(shù)Febc終于有了返回值1 了,它再?gòu)念^開始計(jì)算,然后一直算到n 為止。
通過上面的例子,我們知道遞歸一定要有一個(gè)停止的條件,否則遞歸就不知道停止了。在上面的例子中, if(n<3) return (1); 就是停止的條件。
然而,使用遞歸的代價(jià)是十分巨大的:它會(huì)消耗大量的內(nèi)存!!遞歸循環(huán)時(shí)它用的是堆棧,而堆棧的資源是十分有限的。上面的例子你只能用一個(gè)很小的n值。如果n=20,即Febc(20)的話,它將調(diào)用Febc(N)函數(shù)10000多次!!!而上面一個(gè)例子用循環(huán)也是十分容易寫的:
/*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]; /*實(shí)現(xiàn) Febc(I)=Febc(i-1)+Febc(i-2)*/
printf("\n%d\n",a[n%3]);
}
有興趣者不妨輸入一個(gè)較大的n值,然后比較比較這二個(gè)函數(shù)計(jì)算的速度。當(dāng)然, 如果你使用的n太大的話,遞歸可能發(fā)生錯(cuò)誤。如果死機(jī)了可別罵我哦~~~ 我已經(jīng)提醒過你了 :)
現(xiàn)在我們?cè)賮砜纯匆粋€(gè)求從1 加到100的循環(huán):
/*turboc2*/
main()
{ int i,n;
for(i=1;i<101;i++)
n+=i; }
這很簡(jiǎn)單沒什么可說的。 但是,你能不能寫出相應(yīng)的遞歸函數(shù)呢?
下面就是遞歸(請(qǐng)注意了,這種做法不推薦!! 我只是為了說明問題才這么寫的。)
/*using Turboc2*/
int a=0;
int account(int);
main()
{
account(100);
printf("%d",a);
}
int account(int i)
{
if(i==1) return 1; /*停止條件*/
else
return (n+f(n-1)); /*此句有問題*/
}
在C/C++的問題中,我曾經(jīng)回答過這樣的一個(gè)問題:
若一頭小母牛,從出生起第四個(gè)年頭開始每年生一頭母牛,按此規(guī)律,第n年時(shí)有多少頭母牛? 請(qǐng)問如何用遞歸涵數(shù)求此問題?
先寫出函數(shù)表達(dá)式:f(N)=f(n-1)+f(n-3)
為什么f(N)=f(n-1)+f(n-3)呢,請(qǐng)看:
f(N)-f(n-1)=f(n-3)
因?yàn)榈趎年要比n-1年多的牛,都是大于三歲的牛生的小牛,而f(n-3)正是那些在n年大于三歲的牛,然后它們?cè)诘趎年生下相同數(shù)量的小牛。(請(qǐng)用BorlandC++3.1或其他C++編譯器)
#include<iostream.h>
#include<conio.h>
int cattle(int,int);
void main()
{
int ct,n;
cout<<"Please input the original cattle number:"<<endl; /*輸入起始牛的數(shù)量*/
cin>>ct;
cout<<"Input how many years it past:"<<endl;
cin>>n;
cout<<"You have "<<cattle(ct,n)<<" cattle now!"<<endl;
getch();
}
int cattle(int ct,int n)
{
if(n<4) return (ct); /*停止條件*/
else
return (cattle(ct,n-1)+cattle(ct,n-3)); /*實(shí)現(xiàn)遞歸*/
}
怎么樣,很簡(jiǎn)單吧。 會(huì)用循環(huán)求解嗎?
遞歸在實(shí)際的編程中并不常用,但是在某些情況下,它是非常強(qiáng)有力而漂亮的工具。掌握它的原理時(shí)會(huì)十分有用的。
轉(zhuǎn)自:
?
其它參考:
1、? http://www.nbrkb.net/lwt/jsjsj/sjjg&sf/c++dgyf.htm
2、? http://www.e-van.net/c-prog-hannuo.html
3、? http://www.cppblog.com/haosola/archive/2009/11/17/101163.aspx
4、? http://www.cnblogs.com/eslizn/archive/2011/05/29/2062043.html
5、? http://edu.3gmgc.com/tuwenjiaocheng/C__/diwuzhang_hanshuyuyuchuli/455.html
6、? http://www.asp119.com/program/ccc/2010-09-25/570.html
7、? http://comapp.ecjtu.jx.cn/view.php?id=45
8、? http://webservices.ctocio.com.cn/35/11398035.shtml
9、? http://www.gzu521.com/campus/article/it/200701/139273.htm
總結(jié)
- 上一篇: 举例说明使用MATLAB Coder从M
- 下一篇: OpenCV中cvBlobsLib的编译