• 當前位置:首頁 > IT技術 > 編程語言 > 正文

    C語言函數數的遞歸調用
    2022-04-25 23:00:47

    @TOC

    一、什么是遞歸

    程序調用自身的編程技巧稱為遞歸( recursion) 。遞歸做為一種算法在程序設計語言中廣泛應用。一個過程或函數在其定義或說明中有直接或間接調用自身的一種方法,它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計算,大大地減少了程序的代碼量。遞歸的主要思考方式在于:把大事化小

    遞歸的兩個必要條件:

    1. 存在限制條件,當滿足這個限制條件的時候,遞歸便不再繼續。
    2. 每次遞歸調用之后越來越接近這個限制條件。
      int main()
      {
      printf("hehe
      ");
      main();
      return 0;
      }

      函數自己調用自己,一直打印 “hehe” 但是一會程序自己會停下來。這不是真正的遞歸,是一個死循環(不滿住遞歸的兩個條件)
      ?
      遞歸實現:接收一個整型值(無符號),按照順序打印它的每一位。例如:輸入:1234,輸出:4321

      
      void print(unsigned int n)
      {
      if (n > 9)
      {
          print(n / 10);
      }
      printf("%d", n % 10);
      }
      int main()
      {
      unsigned int num = 0;
      scanf("%u", &num);
      //遞歸-函數自己調用自己
      print(num);
      return 0;
      }
    
    基本的實現邏輯如圖:
    ![image.png](https://s2.51cto.com/images/20220425/1650890354614516.png)
     
    寫遞歸代碼的時候注意:
    1. 不能死遞歸,都有跳出條件,每次遞歸逼近跳出條件
    2. 遞歸層次不能太深(可能會棧溢出)
    
    ## 二、遞歸與迭代
    求第n個斐波那契數,(可以遞歸實現也可以迭代實現)(不考慮溢出)
    我們知道像:1,1,2,3,5,8,13,21,34…… 這樣第n個數等于第n-1個數加上n-2個數的和的一個數列就是**斐波那契數列**
    
    - 遞歸實現求斐波那契數,直接看代碼:
    ```c
    int Fib(int n)
    {
        if (n <= 2)
            return 1;
        else
            return Fib(n - 1) + Fib(n - 2);
    }
    int main()
    {
        int n = 0;
        scanf("%d",&n);
        int ret = Fib(n);
        printf("%d
    ", ret);
        return 0;
    }

    當我們求很小的斐波那契數時,計算機計算很快。但是當我們要求的一個很大的,比如第50個斐波那契數,計算機就會算很久(大概要五分鐘)。大家可以試一試。

    為什么會這么慢呢。因為遞歸實現效率太低,要重復大量的計算(計算層次太多)。
    代碼實現的基本邏輯如圖:
    image.png

    我們可以看一下代碼在計算過程中 n=3(計算第三個斐波那契數) 這一步要執行的次數:
    image.png在計算第40個斐波那契數時,要計算三千多萬次第三個斐波那契數??上攵f歸實現的效率有多低。而且計算太大還會造成程序崩潰。
    ?

    • 循環迭代實現求斐波那契數,直接看代碼:
      int Fib(int n)
      {
      int a = 1;
      int b = 1;
      int c = 1;
      while (n > 2)
      {
          c = a + b;
          a = b;
          b = c;
          n--;
      }
      return c;
      }
      int main()
      {
      int n = 0;
      scanf("%d", &n);
      int ret = Fib(n);
      printf("%d
      ", ret);
      return 0;
      }

      循環迭代的方式計算很快
      ?
      提示

      1. 很多問題是以迭代的形式進行解釋的,這只是因為它比非遞歸的形式更為清晰。
      2. 但是很多問題的迭代實現往往比遞歸實現的效率更低。雖然代碼的可讀性稍微差些。
      3. 當一個問題相當復雜時,難以用迭代實現時,此時遞歸實現的簡潔性便可以補償它所帶來的運行開銷。

    三、典型的遞歸問題

    有興趣的可以了解一下:
    漢諾塔問題,青蛙跳臺階問題
    這都是典型的遞歸問題。

    本文摘自 :https://blog.51cto.com/u

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码