1 if(root==null){ 
2 return 0; 
3 } 
4 int left=maxDeepth(root.left); 
5 int right=maxDeepth(root.right); 
6 return left>right?left+1:right+1;

这是求树的深度。那么程序执行到第四行时,会不会先将left的递归调用压入虚拟机栈中继续向下执行,一直到return。这个算法的思想很简单,但是结合到具体的执行原理,就讲不清了。接下来是研究心得: 

首先假设有这样一棵树:

android 递归优化_递归

程序从树的根节点开始,第一次执行到left=maxDeepth(root.left)时,并没有继续向下,而是停在了这一句,它开始递归,此处不得不提虚拟机栈的一部分知识: 
1.在JVM栈中每调用一次方法就会做一次入栈操作,在栈中保存为一个栈帧(存储方法的局部变量,操作数栈,动态链接,方法返回地址和一些额外的附加信息)。 
2.在JVM栈中永远都是底层栈帧调用上层栈帧。 
假设栈帧就是一个方法的副本(当然真正的远比这复杂),不影响分析。 
下面的每一次调用都会入栈产生栈帧,出栈产生结果给下一层栈帧。 
那么现在0节点入栈了,它执行到left这行,发现要调用一个方法,才能拿到值,所以它根据条件向自己的左儿子节点1要个说法,节点1又向节点3要,3又向7要,7继续向自己的左儿子要结果,但7的左儿子没有是null,所以终于有了确切的结果,返回了0,所以在7这个方法副本中可以继续向下走了,又找7的右节点要结果,这次不用费时间,右,儿子也干净利落的也给了它老子一个0,7号节点所在的这层副本里终于要产生自己最终结果了,7号在比较之后发现自己儿子们的最大身高是0,那么加上7自己这1厘米的身高,就是全家的身高,所以返回了1,此时7这一家从JVM栈中出去了,它的下层副本就是节点3,那么3这层副本呢,既然拿到了自己左儿子的准确身高,就可以向下走了,所以又去问自己的右儿子节点8,同样的道理,8又将自己的左儿子入栈、出栈,之后将自己的右儿子入栈、出栈,获得了自己的最大高度是1,节点3这层副本也就能从栈中出去了,它交出自己的结果给下层副本……………… 
到了这里过程也就很清楚了,递归方法执行到需要递归的地方的时候,不会如代码的过程一样直接继续执行,假设这层的代码就是公式,JVM会去推理,术语叫做递推,得到结果后又一层层把结果带回来,术语叫回溯。这就好像是程序员告诉虚拟机:去吧,皮卡丘,把胜利的果实带回来,然乎皮卡丘又对自己的孩子说:去吧,皮卡丘,把胜利的果实带回来…………然后最小的皮卡丘最终不负期望带回了胜利,一层层把胜利传递回来给程序员。