编程中,一个很重要的方法是递归。
递归:简单来说,自己调用自己。可以将一个较大的问题分解为同类较小规模的问题,有下到上一一求解。即:大规模---同类小规模---解决。
一、递归条件:
1.调用递归函数。一般都是在main函数中调用递归函数。
2.某些条件下,递归函数不再调用自己,结束当前函数的执行。
3.趋近于递归函数不再调用自己的条件。
例如 求最大公约数的公式便符合递归条件,可以用递归实现: 有两个数M,N,则它们的最大公约数gcd 为:
gcd = N , M % N = 0;
gcd(N, R) , M % N = R;
二、栈结构问题
递归可能带来的最大问题是:可能会发生栈溢出(非正常递归-----即无限递归)。 所以必须清楚下面三个点:
1.无限递归如何结束?这里必须满足递归的三个条件:调用递归,在一定条件下不调用自身,让后续调用趋近于结束。
2.递归函数的变量不要太大。
3.递归层数要有预期。
三、递归适用的问题
1.某一类数学公式。例如上述的最大公约数,求阶乘等等。
2.数据结构操作。
3.算法问题。
四、实例
1.正向打印一个数的每一位数:这个问题如果用非递归方式比较难以想像,如果用递归实现则简单又清晰。代码如下:
这里若把第7行和第8行的顺序颠倒,则本函数实现的是倒序打印。如果是这样的话,比较容易用循环实现。
大体实现如下:
for(; num != 0; num /= 10)
{
printf("%d ", num % 10);
}
2.求各位数的和:将问题1的第7,8行改为 return print_num(num / 10) + num % 10;即可实现。
3.strlen函数的递归实现:求字符串长度。代码实现如下:
这里第7行就是递归调用,这里的加一很关键。
五、递归优缺点
优点:简洁,直观,清晰
缺点:开销大,耗费时间空间栈;
时空效率偏低易产生大量重复计算;
最后,我得到了一个启发:写程序效率高,不代表运行效率高。