《C Primer Plus》讀書筆記——遞歸

遞歸的原理

一個函數調用其本身,此調用過程爲遞歸(recursion)。

遞歸的使用

舉個栗子:

/*用來測試UpAndDown函數的驅動程序*/

#include <stdio.h>

void UpAndDown (int);

int main(void)
{
    UpAndDown(1);
    return 0;
}

void UpAndDown (int n)
{
    printf("Level %d: n location %p\n" , n, &n);
    if (n < 5)
        UpAndDown(n+1);
    printf("LEVEL %d: n location %p\n" , n, &n);
}

輸出如下:

輸出如下:

遞歸的基本原理

  • 每級遞歸都使用其私有變量(如例子中的n)

  • 每次函數調用都返回前一級(調用他那級)遞歸

  • 遞歸函數中,位於遞歸調用前的語句和各級被調函數具有相同執行順序

  • 遞歸函數中,位於遞歸調用後的語句和各級被調函數具有相反執行順序

  • 每級遞歸會從頭執行而不是複製其函數代碼,所以一般可代替循環語句。

  • 遞歸函數必須包含可以終止遞歸調用的語句(如if)。

尾遞歸

最簡單的遞歸形式。

把遞歸調用語句放在函數結尾(return語句之前)。

舉個栗子:
計算n的階乘

long fact (int n) // 使用循環計算階乘,佔內存少,執行快
{
    long ans;

    for(ans = 1; n>1; n--)
        ans *= n;
    return ans;
}

long rfact (int n) // 使用遞歸計算階乘,僅作尾遞歸展示、入門long ans;

    if(n > 0)
        ans = n * rfact(n-1);
    else
        ans = 1; //1.零的階乘;2.結束遞歸。
    return ans;
}

遞歸和反向計算

將一個整數轉換成二進制形式。

void ToBinary (unsigned long n) // 簡單須存數組版遞歸
{
    int r;
    r = n % 2;
    if(n >= 2)
        ToBinary(n / 2);
    putchar('0' + r); //or: putchar(r ? '1' : '0')

    return;
}

遞歸的優缺點

優點
算法簡單
缺點
佔內存,難於閱讀和維護

舉個栗子:斐波那契數列:第一、二個數字都是1,而後續的每個數字是其前兩個數字之和。1、1、2、3、5、8、13……

long Fibonacci (int n)
{
    if(n > 2)
        return Fibonacci(n-1) + Fibonacci(n-2);
    else
        return 1;
}

雙重遞歸。
致命弱點:每級調用變量數以指數遞增!

Something interesting …

main( )也可以被自身遞歸調用或其他函數調用,儘管用得少。

發佈了31 篇原創文章 · 獲贊 91 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章