尾递归和JAVA
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尾递归和JAVA相关的知识,希望对你有一定的参考价值。
简单来说,递归即是调用自己本身。所有递归都应该有至少一个基本条件,在满足基本条件时不进行递归。
给出一个递归实例:
1 int fact(int N){ 2 if(N==1) 3 return 1; 4 else 5 return N*fact(N-1); 6 }
每一个递归方法的执行都分为前进和回退两个阶段,上例中计算5的阶乘,前进阶段得到的结果是:
(5*(4*(3*(2*(1)))))
回退阶段则由内向外,依次计算括号中的值。
应用到程序中,分别对应压栈和出栈。考虑到这种做法,每次调用都会压栈出栈,效率很低。除此之外,每次递归创建新的栈在递归深度过深的时候,会引起栈溢出,也就是可以分给创建栈的内存不足的情况。尾递归的方法由此提出。
尾递归,简单来说,就是将递归语句写到最后一行且不参与任何计算。将上例改写为尾递归为:
1 int fact(int N){ 2 if(N==1) 3 return 1; 4 else 5 return fact(N-1,N); 6 } 7 8 int fact(int N, int M){ 9 if(N==1) 10 return M; 11 else 12 return fact(N-1, N*M); 13 }
但这要求编译器能对尾递归进行优化,每次重用或者说覆盖原来递归方法的栈,而不是新建栈。遗憾的是JAVA和python都不支持尾递归的优化,JAVA的尾递归代码与普通递归无异。可能JVM是想在出现异常时更好地输出堆栈信息的缘故。所以,JAVA中一般能用迭代就不用递归。
以上是关于尾递归和JAVA的主要内容,如果未能解决你的问题,请参考以下文章
[Java 8] Lambda表达式对递归的优化(上) - 使用尾递归 .
尾递归 递归函数中,递归调用是整个函数体中最后的语句,且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归,空间复杂度是O