C 递归

递归指的是在函数的定义中使用函数自身的方法。

举个例子:从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?"从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?'从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……'"

语法格式如下:

  1. void recursion()
  2. {
  3. statements;
  4. ... ... ...
  5. recursion(); /* 函数调用自身 */
  6. ... ... ...
  7. }
  8. int main()
  9. {
  10. recursion();
  11. }

流程图:

C 递归 - 图1

C 语言支持递归,即一个函数可以调用其自身。但在使用递归时,程序员需要注意定义一个从函数退出的条件,否则会进入死循环。

递归函数在解决许多数学问题上起了至关重要的作用,比如计算一个数的阶乘、生成斐波那契数列,等等。

数的阶乘

下面的实例使用递归函数计算一个给定的数的阶乘:

实例

  1. #include <stdio.h>
  2. double factorial(unsigned int i)
  3. {
  4. if(i <= 1)
  5. {
  6. return 1;
  7. }
  8. return i * factorial(i - 1);
  9. }
  10. int main()
  11. {
  12. int i = 15;
  13. printf("%d 的阶乘为 %f\n", i, factorial(i));
  14. return 0;
  15. }

当上面的代码被编译和执行时,它会产生下列结果:

  1. 15 的阶乘为 1307674368000.000000

斐波那契数列

下面的实例使用递归函数生成一个给定的数的斐波那契数列:

实例

  1. #include <stdio.h>
  2. int fibonaci(int i)
  3. {
  4. if(i == 0)
  5. {
  6. return 0;
  7. }
  8. if(i == 1)
  9. {
  10. return 1;
  11. }
  12. return fibonaci(i-1) + fibonaci(i-2);
  13. }
  14. int main()
  15. {
  16. int i;
  17. for (i = 0; i < 10; i++)
  18. {
  19. printf("%d\t\n", fibonaci(i));
  20. }
  21. return 0;
  22. }

当上面的代码被编译和执行时,它会产生下列结果:

  1. 0
  2. 1
  3. 1
  4. 2
  5. 3
  6. 5
  7. 8
  8. 13
  9. 21
  10. 34

递归是一个简洁的概念,同时也是一种很有用的手段。但是,使用递归是要付出代价的。与直接的语句(如while循环)相比,递归函数会耗费更多的运行时间,并且要占用大量的栈空间。递归函数每次调用自身时,都需要把它的状态存到栈中,以便在它调用完自身后,程序可以返回到它原来的状态。未经精心设计的递归函数总是会带来麻烦。

采用递归方法来解决问题,必须符合以下三个条件:

  • 1、可以把要解决的问题转化为一个新问题,而这个新的问题的解决方法仍与原来的解决方法相同,只是所处理的对象有规律地递增或递减。

说明:解决问题的方法相同,调用函数的参数每次不同(有规律的递增或递减),如果没有规律也就不能适用递归调用。

  • 2、可以应用这个转化过程使问题得到解决。

说明:使用其他的办法比较麻烦或很难解决,而使用递归的方法可以很好地解决问题。

  • 3、必定要有一个明确的结束递归的条件。

说明:一定要能够在适当的地方结束递归调用。不然可能导致系统崩溃。