函数递归指的是在调用一个函数的过程中又出现直接或间接地调用函数本身。函数递归可分为两个阶段:递推阶段:原问题不断分解为新的子问题,逐渐从未知结果向已知方向推测,最终达到已知条件,即递归结束条件,此时递推阶段结束。回归阶段:从已知条件出发,按照递推的逆过程,逐一求值回归,最后达到递推的开始处,结束回归阶段,完成递归调用。
一般的采取递归的方法设计问题的要求:
(1)要解决的问题可以转化成一个规模较小的新问题,新问题和原问题解决方法相同,不同之处在于所处理问题的规模。
(2)通过转化过程可以使问题逐步简化,直到问题得到解决。
(3)递归问题必须有一个明确的递归结束条件!
回忆一下,正整数是如何定义的?
可能你会回答正整数是1,2,3……,这样的定义对于小学生是没有任何问题的,但是不太严密,可能你喜欢这样的定义:
(1)1是正整数。
(2)如果n是正整数,n+1也是正整数。
(3)只有通过(1)、(2)定义出来的才是正整数。
形象一点:举一个计算阶乘的例子,例如3!
#include<stdio.h>
int f(int n)
{
return n==0?1:f(n-1)*n;
}
int main()
{
printf("%d\n",f(3));
return 0;
}
可以是这样理解:
皇帝:大臣,你给我算一下f(3)。
大臣:知府,你给我算一下f(2)。
知府:县令,你给我算一下f(1)。
县令:师爷,你给我算一下f(0)。
师爷:回县令,f(0)=1。
县令:回知府,f(1)=1。
知府:回大人,f(2)=2。
大臣:回皇上,f(3)=6。
这就说明了从未知的f(3)向已知的f(0)推,然后回推把f(3)也求出来。
其实,汉诺塔问题原理很明白,需要函数递归(详解见本博客中的经典问题)。