首先写出在《数据结构与算法分析:c语言描述》看到的关于写递归的四条基本法则:
1.基准情形
2.不断递进
3.设计法则(假设所有的递归调用都能运行)
4.合成效益法则
首先来看1(基准情形),如果一个递归没有基准的话,那么递归会一直运行下去,因为找不到让递归停下来的点,下面举一个例子:
1.假设我们要求n!,看看用递归函数进行求解时没有基准会发生什么情况
int factorial(int n)
{
return n*factorial(n-1);
}
可以看出上面这个函数会一直运行下去,运行的轨迹为n*(n-1)......*1*0*(-1)*(-2)............
2.现在让我们加上基准再看看程序是怎么运行的
int factorial(int n)
{
if(n==1)
return 1;
return n*factorial(n-1);
}
现在再让我们来看看程序是怎么运行的,当输入为n时,运行轨迹就为n*(n-1)......*2*factorial(1),因为factorial(1)输入
为1,所以递归就停止了。这里n=1为基准,我理解为让递归停止继续往下递归的一个点,当没到这个点的时候,程序一直
在递归运行。
再来看2(不断递进),从上面的分析可以看出,递归是不断递进运行的,它能把一系列大的问题不停地拆分成一个个的小问题,直到达到基准情形。
让我们现在来看看3(设计法则),我认为这是最重要的一部分,往常写或者是看递归程序的时候,我都想要去追踪大量的递归调用。拿前面的阶乘例子来看,假设n=5,我会一步步看是怎么进行递归的,首先是5*factorial(4),然后又会去追踪actorial(4),
当n很小时,这种方法看起来是可取的,当时当n很大时,这种逐步追踪的方法就显得力不从心了。现在我们按照设计法则所讲的
:假设所有的递归调用都能运行 来看看上面阶乘的例子。按照这个法则,首先我们应该认为factorial这个函数能够正确运行,而
n!可以写成n*(n-1),在上面的函数就可以体现为n*factorial(n-1)
关于第四点我还不能理解,以后如果深入的去看递归的话会补充上
最后,如果有理解不对或者不到位的地方,麻烦各位多多指导,谢谢!