尾递归 java_尾递归和JAVA

简单来说,递归即是调用自己本身。所有递归都应该有至少一个基本条件,在满足基本条件时不进行递归。

给出一个递归实例:

1 int fact(intN){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(intN){2 if(N==1)3 return 1;4 else

5 return fact(N-1,N);6 }7

8 int fact(int N, intM){9 if(N==1)10 returnM;11 else

12 return fact(N-1, N*M);13 }

这是有外及里的尾递归,当计算斐波那契数列的时候就要换一种思路,即由里及外。

斐波那契问题描述:每个兔子出生后的第三个月后,每个月都可以生下一对兔子,如果不考虑兔子死亡问题,第一个月有新出生的一对兔子,那第N个月有多少兔子?

其尾递归代码如下:

1 int Fibonacci(int N, int first, int second, intbegin){2 if(begin>=N)5 return first;6 else

7 return Fibonacci(N, second, first+second, begin+1);8 }

但这要求编译器能对尾递归进行优化,每次重用或者说覆盖原来递归方法的栈,而不是新建栈。遗憾的是JAVA和python都不支持尾递归的优化,JAVA的尾递归代码与普通递归无异。可能JVM是想在出现异常时更好地输出堆栈信息的缘故。所以,JAVA中一般能用迭代就不用递归。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值