Java-对递归的理解

递归相信很多人都用过,但所有人都知道递归的秘密吗?

这里我分2中情况理解下递归。

先看段代码:

例1:

    private static void calc(int num) {
        System.out.println("num:" + num);
        num--;
        if (num < 2) {
            return;
        }
        calc(num);
        System.out.println("num after calc:" + num);
    }

输出:

num:5
num:4
num:3
num:2
num after calc:2
num after calc:3
num after calc:4

输出是先递减,然后递增。初次接触,可能会惊讶下,然鹅,对于细心的人,断点调试过的,或许已经发现了这个原理。但是不是又不好解释?没关系,这里第一个例子我先把现象放在这里。

例2:

    private static boolean calc1(int num) {
        if (num < 2) {
            return false; // 返回给递归的 注释1
        }
        System.out.println("num:" + num);
        num--;
        if (calc1(num)) {
            System.out.println("num after calc:" + num);
        }
        return true; // 函数返回 注释2
    }

还是这个例子,第一个没有返回值,大家没注意return的问题,一般情况,return就直接返回了整个方法,但在递归里,发现注释1中返回的是递归调用处,注释2返回的,才是整个函数。整个可以调用下试试。

        boolean calc1 = calc1(5);
        System.out.println("calc1 is return: " + calc1);

calc1 is return: true 

 第一眼看到的,真正终止递归的,是num < 2,那应该是return false 才对吧?为什么是true呢?就是了,因为注释1处的return,是return给if(calc1(num))这里的,是告诉递归者,不能再递归了,你要停止。然后后面的就你就好理解了吧。最终是return true。

大家一般使用,都是递归的处理下问题,遇到某种情况就退出,处理的理解不会有这样的诡异和深刻。好了。这里是一部分人对递归没有理解到的地方。那递归出这样的东西出来,那递归的真正的原理是啥呢?

细心的人观察出来了,

num:5
num:4
num:3
num:2
num after calc:2
num after calc:3
num after calc:4
这个输出,不是先进后出么?

 大概就是这样的,那这个不就是栈吗?对,就是栈。你可以认为递归,就是把需要递归的代码快放在一个栈中,放进栈中的代码,会依次执行,谁先进,谁就先执行了,然后就是等待递归结束,再从栈中弹出来,执行递归之后该执行的动作编译器,不可能在一块代码中,肆无忌惮的递归执行的,只有是搞出另一个方法快出来,然后互相调用,跳转。到这里,大家对递归是不是有一个深刻的认识了?

见过递归的溢出么?

Exception in thread "main" java.lang.StackOverflowError
	at java.io.FileOutputStream.write(FileOutputStream.java:326)
	at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
	at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
	at java.io.PrintStream.write(PrintStream.java:482)
	at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
	at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
	at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
	at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
	at java.io.PrintStream.write(PrintStream.java:527)
	at java.io.PrintStream.print(PrintStream.java:669)
	at java.io.PrintStream.println(PrintStream.java:806)

 你看看,一个死循环的递归,系统就会告诉你,栈溢出了。

至此,递归的一些小秘密。

递归如此特性,那有没有和他完美其他的东西呢?

嗯嗯,下次我整理出完美利用递归特性的东西:归并排序算法。

 看懂这个先,然后再去看归并排序算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值