递归函数详细版(Java)

本文深入探讨了递归的概念、应用场景和实现条件,通过实例解析了递归在计算阶乘、求前N项和、顺序打印数字以及斐波那契数列中的应用。同时,针对递归效率问题,提出了使用循环和尾递归优化的方法,以提高代码执行效率并降低时间空间复杂度。
摘要由CSDN通过智能技术生成

递归函数详细版及相关练习

1.递归的概念

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

2.递归的应用场景

通常应用在一个将大型的复杂问题层层转化为一个与原问题有着相同的解决方案的小问题;

3.递归实现的条件

1)可以将原问题进行拆分,并且拆分成的小问题有着与原问题相同的解决方案;
2)有递归终止的条件;(必须)

4.案例说明

1)求N的阶乘

public class Factorial {
    //递归:求N的阶乘 1*2*3*4*........
    public static long factor(int n){
        if(n==1){
            return 1;  //递归的出口(递归终止的条件)
        }
        return  factor(n-1)*n; //调用方法自身
    }

    public static void main(String[] args) {
        int n=5;
        long  ret=factor(n);
        System.out.println("ret = " + ret);  //120
    }
}

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

下面分析这个求阶乘的递归过程,过程图如下所示:
在这里插入图片描述
程序是按照标识的 (1) -> (8) 的顺序执行往下执行的;当执行到第(4)步时,由于n=1,所以,条件满足了,进入条件里面,返回一个1,返回1这个结果要回到调用的位置继续往下执行,也就是接着进行的(5) -> (8)过程;

需要注意的是,方法从那调用的就要返回到哪里去;

2)求前N项和:1+2+3+4+…

public class Recursion {
    //递归实现求和:1+2+3+4+5+......
    public static long sum(int n) {
        if (n == 1) {
            return 1;    //递归终止的条件
        }
        return  sum(n-1)+n; //调用自身
    }

    public static void main(String[] args) {
        System.out.println(sum(4));  //10
    }
}

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

public class PrintNumBit {
    //递归打印数字的每一位
    public static void print(int num) {
        //num>9,即就是至少是两位数
        if (num > 9) {
            print(num / 10); 
        }
        System.out.println(num % 10);
    }

    public static void main(String[] args) {
        print(1234);
    }
}

  1. 求斐波那契数列的第 N 项(兔子数列)
public class Fib {
    //递归求斐波那契数列的第 N 项
    public static long fib(int n){
        if(n < 3){
            return 1; //递归的终止条件
        }
        return fib(n-2)+fib(n-1); //方法调用自身
    }

    public static void main(String[] args) {
        System.out.println(fib(6));
    }
}

图解如下:

在这里插入图片描述

可以看出,有许多地方都是重复的;因此可以想象当n较大时,程序的执行速度就非常的慢. 原因是进行了大量的重复运算;

那如何避免这个问题呢?
方法
(1)采用循环
(2)尾递归

循环参照代码如下:

public class Fib {
    public static long fibLoop(int n){
        long first=1;
        long second=1;
        long ret=1;
        for(int i=3;i<=n;i++){
            ret=first+second;
            first=second;
            second=ret;
        }
        return ret;
    }

    public static void main(String[] args) {
        System.out.println(fibLoop(50));  //12586269025
     
}
    }

尾递归参照代码如下:

public class Fib {
    public static long fibonacci(int n,int a,int b){
        //采用尾递归
        if(n<3){
            return b;
        }
        return fibonacci(n-1, b,a+b);
    }
     public static void main(String[] args) {
        System.out.println(fibonacci(5,1,1));  //5
    }
}

通过上述两个代码,可以大大提高代码的执行效率;提高了性能;降低了时间和空间复杂度,欢迎指证,不喜勿喷!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值