递归

来源:互联网 发布:网络大电影发行平台 编辑:程序博客网 时间:2024/05/16 11:19

1.递归简介

C语言允许一个函数调用其本身。这种调用过程被称作递归。注意当一个函数调用自己时,如果编程中没有设定可以终止递归的条件检测,它会无限制地进行递归调用。

递归一般可以替代循环语句使用,有些情况下使用循环语句比较好,而有些时候使用递归更有效。递归方法虽然使程序结构优美,但其执行效率却没有循环语句高。

2.一个简单的递归示例

#include <stdio.h>void func(int n){    if (n > 0)    {           printf("n = %d\n", n);         func(n - 1);         printf("n = %d\n", n);     }   }int main(void){    func(5);    return 0;}

可以预见的结果是:

n = 5n = 4n = 3n = 2n = 1n = 1n = 2n = 3n = 4n = 5

那么来简单分析一下这个递归程序的工作过程。 首先main函数中调用递归函数func,并传入参数5.
接着func(5)执行,由于5大于0,所以第一个printf执行,打印出5. 接着,func(4)执行,那么形参n在函数被第2次调用的时候被赋值为4,之后判断,第一个printf执行,打印出4.
同样的,下面的调用分别打印出3,2,1,当打印n=1后,执行func(0),此时n被赋值为0,则无法通过判断,func(0)执行结束返回被调用函数中,也就是func(1)中,现在函数继续执行,打印出n=1. 接着同样的打印出2,3,4,5.

注意:
每一级的递归都使用它自己私有的变量n.也可以通过查看变量的地址来得出这个结论。

3.递归的基本原理

  • 1.每一级的函数调用都有自己的变量。
  • 2.每一次函数调用都会有一次返回。当程序执行到某一级递归的结尾处时,它会转移到前一级递归继续执行。程序不能直接返回到main()中的初始调用部分,而是通过递归的每一级逐步返回,即从func()的某一级递归返回到调用它的那一级。
  • 3.递归函数中,位于递归调用前的语句和各级被调函数具有相同的执行顺序。
  • 4.递归函数中,位于递归调用后的语句的执行顺序和各个被调函数的顺序相反。
  • 5.虽然每一级递归都有自己的变量。但是函数代码并不会得到复制。函数代码是一系列的计算机指令。而函数调用就是从头执行相应函数的指令集,除了会每次创建变量,递归调用非常类似于一个循环语句。
  • 6.递归函数中必须包含可以终止递归调用的语句。

一个递归和循环比较的简单程序:

//递归int mystrlen(const char *s, int n){    if(s[n])        return mystrlen(s, n + 1) + 1;    else        return 0;}//循环int mystrlen2(const char *s) {    int i = 0;    while(s[i])    {           i++;            }       return i;}

这两个函数分别是用递归和循环来自己实现求字符串长度的功能,可以看到两者的区别,递归在此处的复杂度是大于循环的。只是做个演示,在此处是不适合用递归的。

4.递归的优缺点

使用递归既有优点也有缺点,其优点在于为某些编程问题提供了最简单的解决方法,比如二叉树的遍历,著名的斐波纳契数列。而缺点是一些递归算法会很快耗尽计算机的内存资源。同时,使用递归的程序难于阅读和维护。

0 0
原创粉丝点击