java中的递归和以及存在优化的问题

 在过往不知一次的学过递归,每次也能写出,但对其运行的机制以及他的效率都不为之,今天又从新看到递归所以重新学习下,同时也作为我第一篇正式博客的知识。

以下是一个一个最普遍的例子,那个求一个数的阶乘:

public class jiandan_recursion {
    static long foo(int i,long sum){
        if(i==1)
            return 1;
        else
            return foo2(i,sum);
    }

    static long foo2(int i,long sum){
        if(i==1)
            return sum;
        else
            return  foo2(i-1,sum*i);
    }

    public static void main(String[] args) {
        long value=foo(5,1);    //该函数是求5的阶乘
        System.out.println("该数的阶乘为:"+value);
    }
}
该数的阶乘为:120

先开始递归对我来说感觉是一个很神奇的东西,用较少的代码就可以算出你想要的结果,但后来得知递跟非递归相比需要很消耗更多空间和时间,递归需要消耗系统的栈堆,当递归的深度达到一定量是就会造成系统的堆栈溢出。也可得知也会消耗大量的时间。 

      比如看下个例子:递归和非递归(迭代/循环)时间上的差别


    //递归
    static long foo(int i){
        if(i==1)
            return 1;
        return foo(i-1)*i;
    }
    //非递归
    static long foo2(int i){
        long sum=1;
        for(int p=1;p<=i;p++){
            sum*=p;
        }
        return  sum;
    }
    
    public static void main(String[] args) {
        long time1 = System.currentTimeMillis();   //返回当前时间以毫秒为单位
        System.out.println("递归调用前的时间 = " + time1);
        long i = foo(20);
        System.out.println(i);
        long time2 = System.currentTimeMillis();
        System.out.println("递归调用前的时间 = " + time2);
        System.out.println("递归所用的时间 = " + (time2 - time1));
        System.out.println("==================================================================");
        long time3 = System.currentTimeMillis();
        System.out.println("循环调用前的时间 = " + time3);
        long i2 = foo2(20);
        System.out.println(i2);
        long time4 = System.currentTimeMillis();
        System.out.println("循环调用前的时间 = " + time4);
        System.out.println("循环调用所用的时间 = " + (time4 - time3));
    }
递归调用前的时间 = 1552377125450
2432902008176640000
递归调用前的时间 = 1552377125451
递归所用的时间 = 1
==================================================================
循环调用前的时间 = 1552377125451
2432902008176640000
循环调用前的时间 = 1552377125451
循环调用所用的时间 = 0

这个所差的时间可以在运行多次的结果会用一定的差别,但是可以明显的可看当递归的深度达到20次的时候,运算所用的时间用了1-2毫秒,虽然在我们生活中一俩毫秒根本没有感触,但在计算机的世界中便是很长的时间。

所以在尽量能避免使用递归的情况下,就不要使用。

在其他大牛的博客中看到了关于指针优化的问题:尾递归

但是才疏学浅,有点看不懂,所以把这块知识先空着,待我什么参透在来补上。

http://it.deepinmind.com/jvm/2014/04/16/tail-call-optimization-and-java.html

有兴趣的人可以看看,或者在找些别的资料。小弟,先行告退。


猜你喜欢

转载自blog.csdn.net/qq_41965731/article/details/88422331