关于java的递归

发布时间:2024年01月03日

关于java的递归

本篇文章来了解以下java方法的最后一个基础知识,递归,递归是一个非常简便的东西,也是一个非常危险的东西🤣下面向大家仔细说明以下什么是递归,以及递归的注意事项,实现逻辑等。

递归

  • 我们见到过A方法调用B方法,main()方法就是最好的例子。
public class Demo
{
    public static void main(String[] args)
    {
        test();//main方法调用我们定义的方法,A调用B
    }
    
    //随便定义一个方法
    public static void test()
    {
        System.out.println("Hello");
    }
}
  • 递归就是,A调用A,自己调用自己!
  • 但是递归不是一个好的用法,我们下面举例说明一下。
public class Demo
{
    public static void main(String[] args)
    {
        Demo demo =new Demo();
        demo.test();
    }
    
    //自己调用了自己
    public void test()
    {
        test();
    }
}

我们上述的代码中,test方法自己调用了自己,然后再用main方法去调用一次,我们执行一下代码,就会发现如下报错

Exception in thread "main" java.lang.StackOverflowError//栈溢出异常
	at method.Demo.test(Demo.java:12)
	at method.Demo.test(Demo.java:12)
	at method.Demo.test(Demo.java:12)
	at method.Demo.test(Demo.java:12)
.......

我们会发现,报错栈溢出了,这是因为,反复调用自己,没有终止标记,陷入了一个死循环中,导致栈溢出,什么是栈我们在下文中说明一下,所以,递归需要注意递归结构

  • 利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
  • 递归的能力在于用有限的语句来定义对象的无限集合。

递归的结构

  • 递归头:什么时候不调用自己,如果没有头,就会死循环,也就是结束终止标记。
  • 递归体:什么时候要调用自己。

下面用实现阶乘的方法来介绍一下递归的头和体。

public class Demo
{
    public static void main(String[] args)
    {
		System.out.println(sum(5));
    }
    
    //阶乘
    //1! 1
    //2! 2*1
    //5! 5*4*3*2*1
    public static int sum(int n)
    {
        if(n==1)
        {
            return 1;
        }
        else
        {
            return n*sum(n-1);//调用自己,每次减少1
        }
    }
}

我们执行一下代码,发现结果是

120

进程结束.....

我们实现出来,但是可能不太好理解,我们将它分解一下。

假如我们输入的数字是2,实参是2,传到方法中的时候先进行判断,然后进入else,执行2*sum(1),sum(1)的返回结果是1。

我们输入的数字是5

第一步,判断,不满足,返回 5 * sum(4)

到这就可以理解为我们输入了4

第二步,判断,不满足,返回 4 * sum(3)

到这就可以理解为我们输入了3

第三步,判断,不满足,返回 3 * sum(2)

到这就可以理解为我们输入了2

第四步,判断,不满足,返回 2 * sum(1)

到这就可以理解为我们输入了2

第五步,判断,满足,返回1

所以,最终的输出结果,5 * 4 * 3 * 2 * 1,结果为120😀

  • 因为1的阶乘是1本身,所以到1的时候,就结束自身调用了,这个就叫递归头,专业名称叫边界条件
  • 下面的自身调用,就是递归体,叫返回阶段

  • 递归虽然有的时候,可以实现一些复杂运算的代码,但是不建议使用!
  • java中有栈机制的说法,就好比一个容器,main方法调用一次递归方法,就会堆积一层,直到程序执行完,全部释放。
  • 所以,过度使用递归,会导致程序深度过大,内存占用过高,系统崩溃。
  • 我们就刚刚的阶乘来举例说明一下。
public class Demo
{
    public static void main(String[] args)
    {
		System.out.println(sum(100000));//这里输入10万
    }
    
    //阶乘
    //1! 1
    //2! 2*1
    //5! 5*4*3*2*1
    public static int sum(int n)
    {
        if(n==1)
        {
            return 1;
        }
        else
        {
            return n*sum(n-1);//调用自己,每次减少1
        }
    }
}

我们在传参的时候,传一个10万,让它去进行阶乘计算,这样的话就太过于堆积,不断的累加,会让内存无法释放,直到卡死🥲

所以我们说,递归适合用于一些情况下,就相当于循环方法,要有度,尽量不要使用在关键的代码中,向这种十万的阶乘,我们可以考虑用别的算法去实现😀。

文章来源:https://blog.csdn.net/SpringYang11/article/details/135375126
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。