递归
来源:互联网 发布:网络大电影发行平台 编辑:程序博客网 时间: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