1. 程式人生 > >詳解遞迴(基礎篇)———函式棧、階乘、Fibonacci數列

詳解遞迴(基礎篇)———函式棧、階乘、Fibonacci數列

一、遞迴的基本概念

遞迴函式:在定義的時候,自己呼叫了自己的函式。

注意:遞迴函式定義的時候一定要明確結束這個函式的條件!

二、函式棧

棧:一種資料結構,它僅允許棧頂進,棧頂出,先進後出,後進先出。我們可以簡單的理解為棧就是一個杯子,這個杯子裡面有很多隔層,每一層都可以放東西,第一個放入的東西就在杯子最後一層,第二個放入的東西就在倒數第二層,現在我們要取出最後一層的東西,就必須先把第二層的東西給出來。
函式棧:棧裡面每一層都是裝的都是函式的棧就是函式棧,呼叫一個函式的時候,這個函式就入棧,這個函式呼叫完成了(執行到了函式的最後一個語句或者說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數列的在上述程式中如何計算的,我們仍然是通過函式棧進行,具體如何執行在此就不再贅述。