詳解遞迴(基礎篇)———函式棧、階乘、Fibonacci數列
阿新 • • 發佈:2018-11-20
一、遞迴的基本概念
遞迴函式:在定義的時候,自己呼叫了自己的函式。
注意:遞迴函式定義的時候一定要明確結束這個函式的條件!
二、函式棧
棧:一種資料結構,它僅允許棧頂進,棧頂出,先進後出,後進先出。我們可以簡單的理解為棧就是一個杯子,這個杯子裡面有很多隔層,每一層都可以放東西,第一個放入的東西就在杯子最後一層,第二個放入的東西就在倒數第二層,現在我們要取出最後一層的東西,就必須先把第二層的東西給出來。
函式棧:棧裡面每一層都是裝的都是函式的棧就是函式棧,呼叫一個函式的時候,這個函式就入棧,這個函式呼叫完成了(執行到了函式的最後一個語句或者說return了),就出棧。
下面是一個演示函式棧執行機制的C語言程式,並無實際意義,僅用於理解函式棧:
#include<stdio.h> void function1() { printf("function1 done!") return; //第三步,函式function1呼叫完畢,出棧 } void function2() { printf("function2 done!") return; //第五步,函式function2呼叫完畢,出棧 } void function3() { printf("function3 done!") return; //第八步,函式function3呼叫完畢,出棧 } void function4() { printf("function4 done!") function3(); //第七步,呼叫函式function3,入棧 return; //第九步,函式function4呼叫完成,出棧 } int main()//第一步,呼叫主函式,主函式入棧(這個C語言程式的入口) { function1(); //第二步,呼叫函式function1,入棧 function2(); //第四步,呼叫函式function2,入棧 function4(); //第六步,呼叫函式function4,入棧 return 0; //第十步,主函式呼叫完成,出棧(整個程式執行完成) }
三、例項
1、階乘
題目:用遞迴方法實現計算整數n的階乘n!
解析:
首先,我們易知0!=1; 1!=1; 2!=2*1!; 3!=3*2!; 4!=4*3!;……
那麼我們可以得到遞推公式
- n!=1[n=0,1]
- n!=n*(n-1)[n>=2]
從而我們就可以寫出計算階乘的遞迴程式的C語言程式碼,如下:
#include<stdio.h> long Fact(int n); int main() { int n; long result; printf("Input n:"); scanf("%d",&n); result = Fact(n); if(result == -1) printf("n<0,data error!\n"); else printf("%d! = %ld\n", n, result); return 0; } long Fact(int n) { //對傳入函式的值判斷其合法性 if(n < 0) { return -1; } //計算n的階乘的表示式改寫的程式碼 else if(n == 0 || n == 1) { return 1; } else { return (n*Fact(n-1)); } }
當然,寫出來了並不代表我們理解,下圖講解了在這個程式中是如何計算4的階乘的。
2、Fibonacci數列
題目:實現函式表示式Fib(0)=0,Fib(1)=1,Fib(n)=Fib(n-1)+Fib(n-2)。
解析:在這裡題目已經給出了遞迴表示式,那麼我們可以輕鬆地寫出C語言程式碼。
#include<stdio.h>
int Fib(int n)
{
//判斷傳入資料的合法性
if(n < 0)
{
return -1;
}
//遞迴表示式改而寫的C語言程式碼
else if(n == 0)
{
return 0;
}
else if(n == 1)
{
return 1;
}
else
{
return Fib(n-1)+Fib(n-2);
}
}
int main()
{
int n,result;
printf("Input n:");
scanf("%d",&n);
result = Fib(n);
if(result == -1)
{
printf("A illegal data!");
}
else
{
printf("Fib(%d) = %d", n, result);
}
return 0;
}
關於用Fibonacci數列的在上述程式中如何計算的,我們仍然是通過函式棧進行,具體如何執行在此就不再贅述。