从接触递归到现在有了半年时间了,期间写各种关于递归的算法,比如:汉诺塔,遍历二叉树,图的遍历,快速排序等。今天终于对递归的理解上了一个台阶,所以就趁热打铁,把它记录下来。
我们都知道,递归调用的过程就是函数数据压栈的过程,先进后出,也就是当递归的条件不满足的时候,最后调用的函数先返回,先调用的函数数据最后返回,返回也是一层一层向下返回的。递归调用的过程虽然是压栈的过程,但是我们可以把这个过程理解成一颗树。先调用的函数在树根,最后调用的节点在树顶,当条件不满足从树顶返回,不断的退栈,返回值返回上一层节点。
一、等差数列求和
如果有如下函数:
用Java语言表示可以写成:
private static int sum(int n) {
if(n==1)
return 1;
return sum(n-1)+n;
}
这个函数的功能是求等差数列的前n项和,也就是求1+2+3+…+n的和,用递归来表示很简洁明了,那怎么理解呢。比如,我们求:sum(3),我们把它想象成一棵二叉树。如下图
在该二叉树中清晰的表示了各层递归的调用过程。
函数的调用过程为:
f(3)-->(2)-->f(1)
当n==1时,f(1)==1,函数返回,函数返回的顺序为:
f(3)<--f(2)<--f(1)
最后的结果,从二叉树的底层计算,一层层结果累加,
f(1)+2+3=6,所以sum函数调用的结果是返回了结果6。
二、斐波那契
形如:0,1,1,2,3,5,8,13…这样从第三个数开始,每个数是前面两个数的和,这样的数列叫做斐波拉契数列。斐波那契数列函数原型如下:
用代码实现如下:
private static int fib(int n) {
if(n==1)return0;
if(n==2)return1;
return fib(n-1)+fib(n-2);
}
比如,我们求:fib(4),过程转化成二叉树如下:
看二叉树就很容易理解了。f(4)=f(2)+f(1)+f(2)=2.
总之,递归是宏观的去看问题,一层层调用,然后一层层解决,条件不满足就一层层返回。使用递归使代码更简洁,但是递归太深会导致栈溢出,而且递归的效率比较低,但是理解递归有利于帮助我们把递归转成迭代,提高算法的效率。
4579

被折叠的 条评论
为什么被折叠?



