对递归的理解
所有的循环都可以转成递归,但递归不一定可以写成循环。
先贴一张图整体感受下递归:
通俗来讲:递归就是方法自己调用自己,每次传入的参数不同,每调用一次自己就开一个新的函数栈,在每个
栈空间完成自己的事情后再回到上一层栈空间,这样一来递归就可以分为三类:
1)上一层栈空间会利用下一层栈空间的运行结果:这样的话,本层函数栈在完成自己的事情之前,必须先有一次自己调用自己,
得到下一层栈空间的运行结果,然后利用这个结果做好自己的事情,并继续向上层传递自己的执行结果。
这种情况下,之所以整个问题能得到解决,是因为最后一层函数栈能够解决它的问题,即最小规模的问题能够被解决,再利用依赖
关系,使得整个问题都能被解决。
void Recursion() { // Recursive exit Recursion() // Solve problem }
2)下一层栈空间会利用上一层栈空间的运行结果:这样的话,本层函数栈必须先完成自己的事情,得到当前处理结果后,再自己调用自己,
下一层栈空间利用上一层传递下来的运行结果,做好自己的事情,并继续向下传递自己的执行结果。
void Recursion() { // Recursive exit // Solve problem Recursion() }
3)相邻的两层栈空间之间没有结果上的依赖关系:这样的话,可以先做完自己的事情再递归调用,也可以先递归调用,再去做自己的事情。
之所以能使用递归,是由于每一层栈空间所要做的事情都是一样的,或者说所要解决的问题都是一样的,只是问题的规模不同。
无论每一层递归栈是否有依赖关系,我们都要在到达最后一层递归栈后,能够停止继续递归并返回,因为递归栈本身就是一个内存空间,如果不
能停止递归,首先没有意义,其次内存空间会逐步被占满,直到耗尽。所以一定是要设计合适的递归停止条件(Recursive exit)。
递归问题大致满足上面三种情况,需要设计的就是每层函数栈之间参数传递的方法和递归终止程序。