开发中怎么使用递归?

递归

理解场景

递归其实主要有两个关键,第一个就是要可以递,第二个就是要可以归,其实也就是有去有回。

可以想象这样一个场景,你面前有一个门,你手里拿着一把钥匙,你可以用这把钥匙打开这个门,然后打开这个门之后,你发现前面还有一扇门,但是这扇门也可以用你手中的钥匙打开,就这样你一直向里面打开了很多扇门,知道你打开最后一扇门,发现门里面是一睹墙。然后你带着你得到的东西返回到最初的位置。

递归解决问题的时候,可以在递去的过程中处理问题,如下:

function recursion(大规模){
    if (end_condition){      // 明确的递归终止条件
        end;   // 简单情景
    }else{            // 在将问题转换为子问题的每一步,解决该步中剩余部分的问题
        solve;                // 递去
        recursion(小规模);     // 递到最深处后,不断地归来
    }
}

也可以在归来的过程中处理问题,如下:

function recursion(大规模){
    if (end_condition){      // 明确的递归终止条件
        end;   // 简单情景
    }else{            // 先将问题全部描述展开,再由尽头“返回”依次解决每步中剩余部分的问题
        recursion(小规模);     // 递去
        solve;                // 归来
    }
}

递归是在什么时候处理问题,我们可以通过方法里面调用自身的代码的位置来判断,看看解决问题的代码是在调用自身代码的位置之前还是在之后,如果在之前,那么递归就是在递的过程中解决问题,如果是在之后,那么递归就是在归的过程中解决问题。

递归需要的三个条件

明确递归的终止条件

我们知道,递归就是有去有回,既然这样,那么必然应该有一个明确的临界点,程序一旦到达了这个临界点,就不用继续往下递去而是开始实实在在的归来。换句话说,该临界点就是一种简单情境,可以防止无限递归。

给出递归终止时的处理办法

我们刚刚说到,在递归的临界点存在一种简单情境,在这种简单情境下,我们应该直接给出问题的解决方案。一般地,在这种情境下,问题的解决方案是直观的、容易的。

提取重复的逻辑,缩小问题规模

我们在阐述递归思想内涵时谈到,递归问题必须可以分解为若干个规模较小、与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决。从程序实现的角度而言,我们需要抽象出一个干净利落的重复的逻辑,以便使用相同的方式解决子问题。

递归例子

例子1

下面的这个例子是在递的过程中处理问题,如下图:

在这里插入图片描述

private DepartmentVO findDepartmentVO(DepartmentVO result, Long id) {
        if (result.getId().equals(id)) {
            return result;
        }

        if (CollectionUtils.isEmpty(result.getSubDepartments())) {
            return null;
        }

        for (DepartmentVO subDepartment : result.getSubDepartments()) {
            DepartmentVO departmentVO = findDepartmentVO(subDepartment, id);
            if (departmentVO != null) {
                return departmentVO;
            }
        }

        return null;
    }

上面的代码的逻辑,是在一个部门树里面搜索某个部门,result是一个部门树,id是要搜索的部门id。上面这个递归是在递的过程中处理的问题,上面的这个例子很好的说明了递归所需要的三个条件。

例子2

下面的这个例子,也是在递的过程中解决问题:

public static long f(int n){
        if(n == 1)   // 递归终止条件 
            return 1;    // 简单情景

        return n*f(n-1);  // 相同重复逻辑,缩小问题的规模
    }

上面的这个递归,也满足递归的三个条件:

1.终止条件,也就是if(n==1)

2.终止的时候的处理办法,也就是return n*f(n-1),其实也就是返回一个结果

3.抽取重复的逻辑,缩小问题的规模,其实也就是方法中上面的代码

总结

从上面的两个例子中可以看出,递归肯定是先递,然后再归。终止时的处理办法,其实也就是归来的结果。无论你是在递的过程中处理的问题,还是在归的过程中处理的问题,在最后归来的时候,你必须要有一些东西带回来,这就是递归。

什么时候可以用到递归

一个大问题,如果它可以划分成多个小的问题,并且这些小的问题可以用同一种方式解决,那么我们就可以用到递归。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr-X~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值