遞歸演算法c語言
這是Fibonacci數列
無窮數列1,1,2,3,5,8,13,21,34,55,…,被稱為Fibonacci數列。它可以遞歸地定義為F(N)=F(N-1)+F(N-2),N=0或者N=1,函數等於1
B. C語言遞歸演算法
#include<stdio.h>
int calc(int n){
if (n==1) {
return 1;
}else if(n==2){
return 2;
}else{
return n*calc(n-1)-(n-1)*calc(n-2);
}
}
void main(){
int sum=0,i;
for (i = 1; i <= 10; i++) {
sum+=calc(i);
}
printf("sum=%d\n",sum);
}
C. C語言遞歸演算法
本人學c++,c的語法已經淡忘了,但是遞歸不管什麼語言都是一個原理
其實簡單一點來說就像數學裡面的數列的通項公式:
例如一個數列是2,4,6,8,10......
很容易就可以得到通項公式是a[n]=2*n n是大於0的整數
你肯定學過這個數列的另外一種表示方式就是: a[1]=2, a[n]=a[n-1]+2 n是大於1的整數
其實這就是一個遞歸的形式,只要你知道初始項的值,未知項和前幾項之間的關系就可以知道整個數列。
程序例子:比如你要得到第x項的值
普通循環:
for(int i=1; i<=n; i++)
if (i == x)
cout << 2*i; /*cout 相當於 c裡面的printf,就是輸出.*/
遞歸:
int a(int x) {
if (x = 1)
return 2; /* 第一項那肯定是2了,這個也是遞歸的終止條件! */
else return a(x-1)+2; /* 函數自身調用自身是遞歸的一個特色 */
比如x=4,那麼用數學表示就是a(4)=a(3)+2=(a(2)+2)+2=((a(1)+2)+2)+2
其實遞歸方法最接近自然,也是最好思考的一個方法,難點就是把對象建模成遞歸形式,但是好多問題本身就是以遞歸形式出現的。
普通遞歸就是數據結構上的堆棧,先進後出。
例如上面x=4,把a(4)放入棧底,然後放入a(3),然後a(2),a(1),a(1)的值已知,出棧,a(1)=2,a(2)出棧a(2)=a(1)+2=2+2=4,a(3)出棧a(3)=a(2)+2=(a(1)+2)+2=6,a(4)出棧a(4)=a(3)+2=(a(2)+2)+2=((a(1)+2)+2)+2=8
再比如樓上的階乘例子,當n=0 或 1時,0!=1,1!=1,這個是階乘的初始值,也是遞歸的終止條件。然後我們知道n!=n*(n-1)!,當n>1時,這樣我們又有了遞歸形式,又可以以遞歸演算法設計程序了。(樓上已給出譚老的程序,我就不寫了)。
我給出一種優化的遞歸演算法---尾遞歸。
從我給出的第一演算法可以看出,先進棧再出棧,遞歸的效率是很低的。速度上完全比不上迭代(循環)。但是尾遞歸引入了一個新的函數參數,用這個新的函數參數來記錄中間值.
普通遞歸階乘fac(x),就1個x而已,尾遞歸用2個參數fac(x,y),y存放階乘值。
所以譚老的程序就變成
// zysable's tail recursive algorithm of factorial.
int fac(int x, int y) {
if (x == 1)
return y;
else return fac(x-1, y*x);}
int ff(int x) {
if (x == 0)
return 1;
else return fac(x,1);}
對於這個程序我們先看函數ff,函數ff其實是對fac的一個封裝函數,純粹是為了輸入方便設計的,通過調用ff(x)來調用fac(x,1),這里常數1就是當x=1的時候階乘值了,我通過走一遍當x=3時的值即為3!來說明一下。
首先ff(3),x!=0,執行fac(3,1).第一次調用fac,x=3,y=1,x!=1,調用fac(x-1,y*x),新的x=2,y=3*1=3,這里可以看到,y已經累計了一次階乘值了,然後x還是!=1,繼續第三次調用fac(x-1,y*x),新的x=1,y=2*3=6,然後x=1了,返回y的值是6,也就是3!.你會發現這個遞歸更類似於迭代了。事實上我們用了y記錄了普通遞歸時候,出棧的乘積,所以減少了出棧後的步驟,而且現在世界上很多程序員都在倡議用尾遞歸取消循環,因為有些在很多解釋器上尾遞歸比迭代稍微效率一點.
基本所有普通遞歸的問題都可以用尾遞歸來解決。
一個問題以遞歸來解決重要的是你能抽象出問題的遞歸公式,只要遞歸公式有了,你就可以放心大膽的在程序中使用,另外一個重點就是遞歸的終止條件;
其實這個終止條件也是包含在遞歸公式裡面的,就是初始值的定義。英文叫define initial value. 用普通遞歸的時候不要刻意讓自己去人工追蹤程序,查看運行過程,有些時候你會發現你越看越不明白,只要遞歸公式轉化成程序語言正確了,結果必然是正確的。學遞歸的初學者總是想用追蹤程序運行來讓自己來了解遞歸,結果越弄越糊塗。
如果想很清楚的了解遞歸,有種計算機語言叫scheme,完全遞歸的語言,因為沒有循環語句和賦值語句。但是國內人知道的很少,大部分知道是的lisp。
好了,就給你說到這里了,希望你能學好遞歸。
PS:遞歸不要濫用,否則程序極其無效率,要用也用尾遞歸。by 一名在美國的中國程序員zysable。
D. c語言算n的階乘的遞歸演算法
思路:遞歸求階乘函數,如果輸入的參數等於1則返回1,否則返回n乘以該函數下次遞歸。
參考代碼:
#include<stdio.h>
intfun(intn)
{
if(n==1||n==0)return1;//如果參數是0或者1返回1
returnn*fun(n-1);//否則返回n和下次遞歸的積
}
intmain()
{
intn;
scanf("%d",&n);
printf("%d ",fun(n));
return0;
}
/*
5
120
*/
E. C語言遞歸演算法的原理是什麼
調用自身,完成重復性工作。也就是在函數或子過程的內部,直接或者間接地調用自己的演算法。
如:3! = 2! * 3 2! = 1! * 2 1! = 1
所以;
s(n) {
if (n == 1 || n == 0)
return (1);
else
return (n * s(n-1));
}
F. C語言二叉樹遞歸演算法怎麼做
#include<stdio.h>
#include<string.h>
structtreenode{
intvalue;
treenode*left;
treenode*right;
};
typedeftreenode*BiTree;
voidvisit(treenode*node)
{
printf("%2d",node->value);
}
//結點總數
intnode(BiTreeT)
{
if(!T){
return0;
}
returnnode(T->left)+node(T->right)+1;
}
//前序
voidpreOrder(BiTreeT)
{
if(T){
visit(T);
preOrder(T->left);
preOrder(T->right);
}
}
//中序
voidinOrder(BiTreeT)
{
if(T){
inOrder(T->left);
visit(T);
inOrder(T->right);
}
}
//後序
voidpostOrder(BiTreeT)
{
if(T){
postOrder(T->left);
postOrder(T->right);
visit(T);
}
}
//葉子節點數
intleafnode(BiTreeT)
{
if(T){
if(!T->left&&!T->right)
return1;
else
leafnode(T->left)+leafnode(T->right);
}else{
return0;
}
}
intheight(BiTreeT)
{
if(T){
intlh=height(T->left);
intrh=height(T->right);
return(lh>rh?lh:rh)+1;
}else{
return0;
}
}
intmain()
{
return0;
}
G. C語言如何用遞歸演算法求1!+2!+3!+...n!
#include<stdio.h>
float fun(int n)
{
if(n==1) return 1;//如果n=1則直接返回1
return n*fun(n-1);//否則返回n*fun(n-1),以此計算n的階乘,這條語句就是遞歸體
}
void main()
{
int i;
float sum=0;
for(i=1;i<=n;i++){
sum+=fun(i); //循環調用,用sum累計
}
printf("sum=%.2f\n",sum);
}
H. c語言遞歸演算法
用遞歸法計算n!
用遞歸法計算n!可用下述公式表示:
n!=1 (n=0,1)
n×(n-1)! (n>1)
按公式可編程如下:
long ff(int n)
{
long f;
if(n<0) printf("n<0,input error");
else if(n==0||n==1) f=1;
else f=ff(n-1)*n;
return(f);
}
main()
{
int n;
long y;
printf("\ninput a inteager number:\n");
scanf("%d",&n);
y=ff(n);
printf("%d!=%ld",n,y);
}
程序中給出的函數ff是一個遞歸函數。主函數調用ff 後即進入函數ff執行,如果n<0,n==0或n=1時都將結束函數的執行,否則就遞歸調用ff函數自身。由於每次遞歸調用的實參為n-1,即把n-1的值賦予形參n,最後當n-1的值為1時再作遞歸調用,形參n的值也為1,將使遞歸終止。然後可逐層退回。
下面我們再舉例說明該過程。設執行本程序時輸入為5,即求5!。在主函數中的調用語句即為y=ff(5),進入ff函數後,由於n=5,不等於0或1,故應執行f=ff(n-1)*n,即f=ff(5-1)*5。該語句對ff作遞歸調用即ff(4)。
進行四次遞歸調用後,ff函數形參取得的值變為1,故不再繼續遞歸調用而開始逐層返回主調函數。ff(1)的函數返回值為1,ff(2)的返回值為1*2=2,ff(3)的返回值為2*3=6,ff(4)的返回值為6*4=24,最後返回值ff(5)為24*5=120。
I. C語言遞歸演算法是怎麼執行的
遞歸就是自己調用自己,例如你寫的 net()函數,函數自己調用自己。
它調用自己的時候,不管程序運行到了哪,見到自己直接跳轉,進入到下一個自己中運行,直到不滿足跳入下一個自己的條件時,運行完當前函數,然後回到前一個自己中,回到跳出位置,繼續運行沒有完事的部分,直到完成當前函數,然後回到上一個自己。。。。這樣直到回到第一個自己,運行開始跳出時沒有完成部分的程序。這就是遞歸;
J. c語言 遞歸演算法
1 你得到 的代碼,就應該知道fac的作用
2 是結束遞歸條件
3、是結束時終值