个人学习系列 - 递归

一开始的时候对算法非常的抵触,可能是因为自己太笨了吧。所以想来想去都不能很好的将算法学明白,不过我们要直面恐惧,所以勇敢的面对自己的弱点吧!

递归的含义

一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的。用递归过程定义的函数,称为递归函数,例如连加、连乘及阶乘等。凡是递归的函数,都是可计算的,即能行的。

递归的三个步骤

在我们考虑使用递归的时候,我们需要明确该问题是否适合使用递归的算法,那么我们就需要从以下三个方面对该问题进行拆解。

1. 明确函数要做什么

这个比较关键,因为我们首先要明确的知道我们需要解决什么问题,这样我们才能进行下一步。
例如:我这边想写一个n的阶乘。

    /**
     * 计算n的阶乘
     * @return
     */
    private int factorial(){
        // 具体算法
    }

2. 明确递归结束或退出的条件

由于递归就是函数自己不断的调用自己,如果没有有效的结束或退出条件的话,那么就会造成死循环。这个结束或退出的条件也必须是可预见的,不能是那种模棱两可,是程序运行阶段必须会执行到的。
例如:n的阶乘这个方法,我们可以知道的就是求一个数的阶乘,就是递减的去相乘,当然可以使用循环来实现阶乘。不过写起来就不是很美观了。跑题了,话说回来,我们明确的知道,阶乘的最后一位就是1,所以我们递归结束或退出的条件就是n=1。

    /**
     * 计算n的阶乘
     * @return
     */
    private int factorial(int n){
        
        // 如果n等于1的时候,递归结束。
        if(n == 1){
            return n;
        }
        
    }

2.1 递归结束条件是固定的吗?

当然了,算法有千千万,解决方法也有千千万,所以递归结束条件也不能是固定不变的。
就拿阶乘这个递归来说吧,我们知道任何数乘以1还是原来的数,所以这个n等于1结束递归就不是那么的严谨了,我们也可以在n等于2的时候结束递归。

    /**
     * 计算n的阶乘
     * @return
     */
    private int factorial(int n){
        
        // 如果n等于2的时候,递归结束。
        if(n == 2){
            return 2;
        }
        
    }

上面是不是有问题呀,对了,如果n等于1的时候是不是就出现错误了。
所以我们这里修改一下,当n<=2的时候返回n就好了。

    /**
     * 计算n的阶乘
     * @return
     */
    private int factorial(int n){
        
        // 如果n小于等于2的时候,递归结束。
        if(n <= 2){
            return n;
        }
        
    }

3. 寻找函数的等价关系(关键)

最关键的一步就是寻找等价关系这一步了,这里我们还是寻找一下n的阶乘的等价关系。这里我们就是递减相乘的策略,其实就是n (n-1)...,这样我们如果用方法关系来表示的话就是n factorial(n-1),我们就可以把方法完善一下了。

    /**
     * 计算n的阶乘
     * @return
     */
    private int factorial(int n){
        
        // 如果n小于等于2的时候,递归结束。
        if(n <= 2){
            return n;
        }
    // 等价关系
    return n * factorial(n - 1);        

    }

哈哈,刚才测试100的阶乘的时候发现返回值为0,搞不明白,最后发现溢出了。

个人网站链接

http://www.zhouzhaodong.xyz

你可能感兴趣的:(java)