递归那些事

本文深入探讨了递归的概念,通过实例解释了如何将复杂问题分解为相似的小问题,并展示了递归的实现条件。递归执行过程通过阶乘计算示例进行了分析,揭示了递归可能导致的效率低和栈溢出问题。同时,文章提到了尾递归优化,以减少计算中的重复和提高效率。最后,讨论了递归在代码简洁性和特定算法(如树遍历)中的优势。
摘要由CSDN通过智能技术生成

什么是递归?

一个方法直接或间接的调用自己,适用于把一个大型的复杂问题层层转化为一个与原问题相似的规模较小的问题求解。
例:求1+2+3+…+N
将原问题划分为若干小问题
假设:sum(n)表示1+2+3+…+n-1+n==>sum(n-1)+n;
sum(n-1)= 1+2+…+n-2+n-1==>sum(n-2)+n-1;

sum(2)=sum(1)+2;
sum(1)=1(此时问题可以直接求解,即递归的出口)
最终
在这里插入图片描述

    public static long sum(int n){
        if (n==1){
            return 1;
        }else {
            return sum(n-1)+n;
        }
    }

递归的实现条件

1.对原问题进行拆分,拆分成一个个的小问题,而且小问题还要与原问题解法相同
2.必须要有递归的出口

递归执行过程分析

递归的程序的执行过程不太容易理解, 要想理解清楚递归, 必须先理解清楚 “方法的执行过程”, 尤其是 “方法执行结束之后, 回到调用位置继续往下执行”.
代码示例: 递归求 N 的阶乘

public static void main(String[] args) {
 int n = 5;
 int ret = factor(n);
 System.out.println("ret = " + ret);
}
public static int factor(int n) {
 System.out.println("函数开始, n = " + n);
 if (n == 1) {
 System.out.println("函数结束, n = 1 ret = 1");
 return 1;
 }
 int ret = n * factor(n - 1);
 System.out.println("函数结束, n = " + n + " ret = " + ret);
 return ret; }
// 执行结果
函数开始, n = 5
函数开始, n = 4
函数开始, n = 3
函数开始, n = 2
函数开始, n = 1
函数结束, n = 1 ret = 1
函数结束, n = 2 ret = 2
函数结束, n = 3 ret = 6
函数结束, n = 4 ret = 24
函数结束, n = 5 ret = 120
ret = 120

执行过程图
在这里插入图片描述
程序按照序号中标识的 (1) -> (8) 的顺序执行.

递归的优缺点

优点

1.让代码简洁
2.在树的前序,中序,后序遍历算法中,递归的实现明显要比循环简单得多。

缺点

1.效率低
递归由于是函数调用自身,而函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址以及临时变量,而往栈中压入数据和弹出数据都需要时间。递归中很多计算都是重复的,由于其本质是把一个问题分解成两个或者多个小问题,多个小问题存在相互重叠的部分,则存在重复计算,如fibonacci斐波那契数列的递归实现。
2.可能出现栈溢出
调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出。

尾递归

尾递归,比线性递归多一个参数,这个参数是上一次调用函数得到的结果;所以,关键点在于,尾递归每次调用都在收集结果,避免了线性递归不收集结果只能依次展开消耗内存的坏处。
例如:求斐波那契数列

    public static int fib_rec(int n,int a,int b){
        if (n==1){
            return a;
        }else {
            return fib_rec(n-1,b,a+b);
        }
    }
    public static void main(String[] args) {
        System.out.println(fib_rec(5,1,1));
    }

执行结果:5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值