递归的本质是自己调用自己。要理解这个问题,先看一看函数的调用过程:函数A调用B,它自己并没有结束,本身所占用的资源仍然存在,这个时候它调用B,首先要保存自身的环境,然后跳转,开辟新的空间执行被调用的函数B,这个时候,栈被占用的资源是A+B,如果B再调用函数C,则是A+B+C,如此不断往里钻入,栈不断缩减;再看另外一种情形,在函数A中,依次调用函数B和函数C,这与前面有区别,在函数B执行完毕之后,资源被释放,然后再调拨资源执行函数C,这种情形,资源的占用不是往深入钻的。搞明白了这两种函数调用的原理,就明白人家为什么说,编程的时候函数要尽量发散。
递归是典型的第一种情形,它调用自身,此时自己还未结束,它要等被调用的函数执行完毕之后,自己才会完毕,所以递归的显著特征,是后进先出,后执行的函数先獲得结果,前面的函数才等獲得结果,最先的函数,最后获得输出。这是不断深入、积累占用资源的情况,每调用一次自己,空间加一倍,如果调用函数一次,分配不少的栈资源,那么栈空间很快会消耗干净,尤其在较大型的程序中,这个递归不知道在栈的哪个深度上启动,若迭代次数还要很多,那么资源的耗费是很可观的。注意:调用函数是要消耗时间的!诸如执行阶乘、字符串倒序之类简单的任务来说,递归调用函数的开销比直接的循环代码大得多,也慢得多,是最低效无能的方案。
递归要怎么用?要用得其所!千万不要滥用,更不要当屠龙术去苦练。在追求效率的程序员角度看来,递归是最后的方案,迫不得已时采用。凡是搞优化,首先是拿递归开刀。