总结一下我对递归的理解

从经典的递归例子-----求阶层来说起

int f(int n)
{
	if(n==0)//递归边界
            return 1;
	return n*f(n-1);//递归内容
}

如果我们用上述的代码来求 4 的阶层, 那么方法的调用关系将会是下面这样

f(4)

f(4)=4*f(3)

f(3)=3*f(2)

f(2)=2*f(1)

f(1)=1*f(0)

f(0)=return 1

方法入栈情况如下, f(4)先入栈, 由于f(4)调用了f(3)所以f(3)也要入栈.....以此类推

f(0)
f(1)
f(2)
f(3)
f(4)

然后程序执行到 f(0)的时候, 遇到了return,这时 f(0)方法执行结束, 它将出栈,出栈前它会把返回值返回给它的调用者(f(0)的调用者是f(1)), 

然后轮到了f(1)执行, f(1)执行的时候将不再从判断递归边界的那个地方开始执行, 而是直接从return开始执行, 大家可以打个断点自己亲自试一下(这便是递归的难理解的地方所在), 

打个比方

就好比你是一个人, 你打开一扇门走进这间屋子里面, 你要判断一下这个屋子里面还有没有另一扇门 【相当于判断当前自己是不是已经在递归的出口了, 在本例中相当于判断n是不是为0】, 然后你发现屋子里面还有一扇门, 那你别无选择,只能去开这扇门, 因为你要想执行完整段程序,你就必须找到程序的出口(相当于你必须一直往前走不断的开门, 直到你走到的这间屋子里面不再有另一扇门了, 好了,这时候你知道你已经到达递归的出口了(最后一间屋子), 这时你需要把先最后一间屋子里面的事情做完【在本例中最后一间屋子就相当于f(0),即先要把f(0)执行完,只不过这里的f(0)函数里做的事情非常简单罢了】,然后关门【相当于 f(0)中的return】,关门的意思相当于告诉倒数第二扇门我最后一间屋子中的所有操作已经结束了, 门已经关上了, 最后一间屋子已经没有用了, 可以byebye了【相当于f(0)方法方法已经出栈了,在出栈前它把该返回的东西返回给了它的调用者f(1)】 然后你可以原路返回了, 原路返回去干什么呢? 当然是去做你一路走来所经的这些屋子里面你除了开门以外其它没有做的东西, 而不是再去判断这间屋子有没有门了,因为你在来的路上已经都判断过了一遍了,【在本例中相当于返回的时候不再去执行if判断了】所以你不需再去判断有没有门,只需要去做这个屋子中其他的事情,【这个其它事情就是指的是函数体里面要做的事情,比如f(1)=1*f(0)】你发现一路走来你一直在开门(一直在递归), 递归以外的代码还没有做,所以返回时你要做的就是这些代码), 然后你一间屋子一间屋子的返回,最后你就回到了起点,这时你站在起点把第一扇门关上了(相当于f(4)方法执行结束,方法出栈)并且把你一路上递(递去)归(归来)的所有成果带了出来,返回给了调用者(调用者就是main函数),至此你的旅程就结束了

我学习递归的过程也是非常的痛苦,这也是我在实践过程中对于递归的理解, 可能有说的不对的地方,还请大佬们多提建议。

猜你喜欢

转载自blog.csdn.net/qq_34741578/article/details/87999085