Java-递归

目录

1.递归的相关介绍

1.1 故事引例

1.2 递归的概念

1.3 递归执行过程分析

2.详例

2.1 递归求N的阶乘(详解如何进行递归)

2.2 按顺序打印一个数字的每一位(1234)

2.3 递归求1+2+3+4+...+10

2.4 写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回 1+7+2+9,它的和是19

2.5 求斐波那契数列的第 N 项


1.递归的相关介绍

1.1 故事引例

相信大家都听过一个故事:

从前有坐山,山上有座庙,庙里有个老和尚给小和尚将故事,讲的就是:

"从前有座山,山上有座庙,庙里有个老和尚给小和尚讲故事,讲的就是:

"从前有座山,山上有座庙..."

"从前有座山……"

"

上面的故事有个特征:自身中又包含了自己,因为有些时候,我们遇到的问题直接并不好解决,但是发现将原问题拆分成其子问题之后,子问题与原问题有相同的解法,等子问题解决之后,原问题就迎刃而解了,这也正是递归的思想

1.2 递归的概念

一个方法在执行过程中调用自身, 就称为 "递归"

递归相当于数学上的 "数学归纳法", 有一个起始条件, 然后有一个递推公式.

例如, 我们求 N!

起始条件: N = 1 的时候, N! 为 1. 这个起始条件相当于递归的结束条件.

递归公式: 求 N! , 直接不好求, 可以把问题转换成 N! => N * (N-1)!

递归的必要条件:

1. 将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同

2. 递归出口

1.3 递归执行过程分析

递归的程序的执行过程不太容易理解, 要想理解清楚递归, 必须先理解清楚 "方法的执行过程", 尤其是 "方法执行结束 之后, 回到调用位置继续往下执行"

2.详例

2.1 递归求N的阶乘(详解如何进行递归)

public class Test {
    public static void main(String[] args) {
        int n = 3;
        int ret = fac(n);
        System.out.println(ret);//6
    }

    public static int fac(int n){
        if(n == 1){
            return 1;
        }
        return n * fac(n-1);//fac调用函数自身
    }
}

递归的详细操作:(用三个图详解)

2.2 按顺序打印一个数字的每一位(1234)

public class Test {
    public static void main(String[] args) {
        int n = 1234;
        num(n);
    }
    public static void num(int n){
        if(n >= 9){
            num(n/10);
        }
        System.out.println(n % 10);
    }

}

2.3 递归求1+2+3+4+...+10

public class Test {
    public static void main(String[] args) {
        int sum = 10;
        int ret = sum(10);
        System.out.println(ret);
    }
    public static int sum(int n){
        if(n == 1){
            return n;
        }
        else{
            return n + sum(n-1);
        }
    }
}

2.4 写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回 1+7+2+9,它的和是19

public class Test {
    public static void main(String[] args) {
        int n = 1729;
        int ret = sum(n);
        System.out.println(ret);
    }
    public static int sum(int num){
        if(num < 10){
            return num;
        }
        return num % 10 + sum(num / 10);
    }

}

2.5 求斐波那契数列的第 N 项

public class Test {
    public static void main(String[] args) {
        System.out.println(fib(5));
    }
    public static int fib(int n){
        if(n == 1){
            return 0;
        }
        if(n == 2){
            return 1;
        }
        return fib(n-1) + fib(n-2);
    }
}

那么既然递归如此方便,我们就要盲选递归么,当然不是,就拿斐波那契数列来说

看以下代码:

public class Test {
    public static int count = 0;
    public static void main(String[] args) {
        System.out.println(fib(40));
        System.out.println(count);
    }
    public static int fib(int n){
        if(n == 1){
            return 0;
        }
        if(n == 2){
            return 1;
        }
        if(n == 3){
            count++;

        }
        return fib(n-1) + fib(n-2);
    }
}

 

如上图运算结果所示当求fib(40)时,count出现了次,出现了冗余运算,此时的执行效率其实并不如循环方法。

那么让我们看看循环方法:

public class Test {
    public static void main(String[] args) {
        int n = 40;
        int ret = fib(n);
        System.out.println(ret);
    }
    public static int fib(int n){
        int l1 = 0;
        int l2 = 1;
        int l3 = 0;
        for(int i = 3; i <= n; i++){
            l3 = l1 + l2;
            l1 = l2;
            l2 = l3;
        }
        return l3;
    }
}

 所以并不能盲选递归,当数据大的时候,其实循环效率会更高

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值