怎么理解java中的递归_JAVA如何理解递归?

首先我们强调一下,对于人来说,递归就是一个方法自己调用自己。但对于机器来讲,从来没有什么递归而已,都是方法压栈了n次。

public static int sum(int num){

if(1 == num){

return 1;

} else {

return num + sum(num - 1);

}

};

这是一个常见的递归求和的案例,如果num=5,对于人来讲是一个sum函数不停的调用自己,那么对于电脑来讲是一个5个函数依次调用,只不过这5个函数长的一样都叫sum而已。

public static int sum5(int num){

return num + sum4(num - 1);

};

public static int sum4(int num){

return num + sum3(num - 1);

};

public static int sum3(int num){

return num + sum2(num - 1);

};

public static int sum2(int num){

return num + sum1(num - 1);

};

public static int sum1(int num){

return 1;

};

如果这么写,我相信所有人都能很容易理解,sum5~sum1是五个互相独立,毫不相干的函数,一个函数调用另一个函数是很常规的操作。那么如果在sum5~sum1五个函数都长得一模一样的时候,我们完全可以把sum4,3,2,1都换成sum5,不需要再重复写了,程序存着的目的就是为了消除重复,那就变成了sum5调用sum5,也就是所谓的自己调用自己了。

但在计算机内部,我们必须认识到,依然有5个函数压倒了栈里,而不是一个。所以我们不要把递归脑补成一条蛇吞自己尾巴的图像,很容易大脑死机。自动脑补5个相同函数压栈

我们可以把递归视为多个方法调用的一种特殊情况(多个方法长的都一样)。

鉴于我们人的大脑比较容易理解循环,而不是特别容易接受递归,在实际应用中,建议我们可以还按正常的方法调用来写。如果方法间调用长的一模一样的情况下,自然而然就会考虑多个方法合并一下,也就成了递归。

递归有两个特性,一个是必须有边界条件,还有一个是收敛性。

边界条件就是我们为了避免方法间的无限调用而专门设定的退出时机。不然无限压栈容易栈溢出,而且哪怕设定了退出条件但依然压栈特别多,也容易栈溢出,所以说在java语言里,鉴于递归的低效性,使用的场景不是特别多,所以java程序员即便不熟悉递归,也不影响工作。

递归的收敛性也有另一个说法,叫 降阶。请回头看开头第一个示例中,我们把参数n降阶为n-1的操作,这也是为什么很多递归求和,求阶乘都是倒序计算。

中世纪时经院哲学的代表人物托马斯·阿奎那在他的哲学观点中提出了对上帝的证明方法,他推理的思路大概是:一个事物能够运动都是它前一个事物推动的,就像一个箱子能够运动必然是由前一箱子推动了它,我们以此类推,根据亚里士多德“无限后退不可能”的原则必然收缩有一个最初动力因,它是它自己的原因,这就是上帝。

其实这个收敛性+边界条件就是哲学观点“无限后退不可能”的一个体现,收敛性类似无限后退,边界条件就是那个上帝。

难怪有人说,人理解循环,神理解递归。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值