递归是程序运行时的一种现象,也是解决某些特定问题时较迭代算法来说更自然更优雅的代码组织方式。作为程序员工作了多年后,我发现一个能不能理解好递归,能不能用递归来解决问题是区分程序员和非程序员,甚至于区分好程序员和差程序员的试金石。很多人通过学习掌握了某些语言的语法,也能写一些代码,但是一遇递归就头大。我曾经也是经历过这样的一段时间,所以希望这篇文多少能对这样的人有点帮助。
谈到递归,程序设计课程老师可能会说递归就是「函数自己调用自己」。比如下面的代码段:
void foo()
{
// 自己调用自己就是递归
foo();
}
我们知道这个函数要是运行起来,除了让你的程序报出一个「堆栈溢出」的错误外,其他什么作用也没有。在某种程度上说,我们的大脑就是一个计算机。当我们尝试去理解「自己调用自己」这句话时,大脑也会陷入一个无限的递归过程里,然后「轰」的一声「堆栈溢出」了,所以也就无法去理解了。当然老师还会告诉你递归除了「自己调用自己」外,还有很重要的一部分就是在满足条件的时候函数会返回,这样就避免出现无限递归的过程了。所以一个完整的递归函数组成如下:
void foo()
{
// 返回部分
if (condition)
{
return;
}
// 递归部分
foo(