关于递归的一些个人简单理解

关于递归的一些个人理解

熟练的运用递归往往能写出非常简洁的代码,但是正是由于代码太过简洁,就会导致递归可能有点难于理解,每次在学习递归的时候,都是似懂非懂的样子,一旦想的很深入,就很容易把自己陷进去,刚理解的就好像又乱了。

这几天总结了一个有关递归的心得,写下来希望分享一下,也希望得到大神的指点。

1.什么问题可以用递归解决

首先解题时如果遇到大问题可以拆解同样的更小的问题的情况,大部分都可以用递归来解决。比如最典型的阶层,斐波那契数列,二叉树的遍历,汉诺塔等。

2.怎么去写这个递归函数recursion()

首先,我们必须明确一点,写这个递归函数是干什么的,也就是这个函数的功能,这一定要明确,然后我们需要找到这个递归函数的出口。

我们从最简单的递归说起,就比如阶层的计算中fun(n)这个用来递归的函数是为了计算n的阶层的,这点首先要明确。

    int result = 0;
    pubic int fun(n){
        if (n == 1){
            return 1;
        }
        return n*fun(n-1);
    }

不妨我们取n=5;计算的5的阶层即为54321,其实它可以变成54!又可以变成543!,这里变得每一步都是一个更小的阶层,什么时候我们不需要计算阶层直接得到结果呢,显然是1的时候,这就是递归函数的出口。
那么进入递归函数的内部,你传入一个5是为了计算5的阶层,为了计算5的阶层,那你必须先知道4的阶层,即5
4!,那什么函数可以计算4的阶层呢,就是fun(4),所以直接5*fun(4)就可以了。你不需要再往深处想,这样就够了。

可能听了上面这个还是似懂非懂,那就再说一个经典的问题,汉诺塔问题,不太清楚的先去百度一下汉诺塔的情况。
汉诺塔问题递归函数的出口其实就是当只有一个盘的时候,直接移动就好,不需要其他操作,这里我定义了一个递归函数hanoiTower(num,x,y,z)表示**将num个盘子从x移到z,y作为一个辅助的。**这句话就是这个递归函数功能,认准他就好了

public class Hanoitower {
    static int count = 0;
    public static void main(String[] args) {
        hanoiTower(20,'x','y','z');
        System.out.println(count);
    }
    /**
     * num代表还有几个盘
     * x为原盘
     * y为辅助盘
     * z为目标盘
     */
    public static void hanoiTower(int num,char x,char y,char z){
        count++;
        if (num ==1){
            System.out.println("第1个盘从"+x+"------>"+z);
        }
        else{
            //1.当num>=2,都可以看成两个盘,最下面的盘和他上面的所有盘,我们总是
            //将上面的所有盘先移到辅助盘上
            hanoiTower(num-1,x,z,y);
            System.out.println("第"+num+"个盘从"+x+"------>"+z);
            hanoiTower(num-1,y,x,z);
        }
    }
}

出口找到了,那我们进入递归函数的内部,要想把num个盘从x移动到z,我们是不是要借助y,也就是我们要把num-1个盘先从x移动到y,才能直接把最大的盘移到z,这个功能是不是就是num-1个盘x到y,z做辅助,不就是hanoiTower(num-1,x,z,y)嘛,这时候,我们就可以把最底下的盘子放到z了,所以就输出System.out.println("第"+num+"个盘从"+x+"------>"+z);,而这时候,有需要把移动到y上的sum-1个盘子移到z,这时候x做辅助,hanioTower(sum-1,y,x,z)是不是就可以实现,那么整个递归函数也就写完了。

3.总结

关注递归函数的功能,找到递归函数出口,从整体看问题,不要把自己往递归里绕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值