递归调用栈(算法图解)

本文详细解析递归函数的工作原理,通过实例探讨基线条件和递归条件,并介绍调用栈在递归过程中的作用。以阶乘函数为例,展示了如何避免无限循环并理解函数调用层次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归

每个递归函数都有两部分:基线条件(base case)和递归条件(recursive case)。

递归条件指的是函数调用自己,而基线条件则指的是函数不再调用自己,从而避免形成无限循环。

调用栈:用于存储多个函数的变量。

//1.调用greet("sally"),计算机将首先为该函数调用分配一块内存
def greet(name): 
     //2.此时打印hello,sally!
     print "hello, " + name + "!"  
     //3.此时调用了greet2("sally")
     greet2(name) 
     //7.打印准备说再见啦
     print "准备说再见啦..." 
     //8. 此时调用bye 
     bye() 
    
//4.进入greet2,同样为它分配一块内存
def greet2(name): 
    //5.打印 你好吗,sally?
    print "你好吗, " + name + "?"  
//6.这时greet2函数调用完毕,从栈顶弹出

//9.进入bye,同样为它分配一块内存
def bye(): 
    //10.打印 好的拜拜啦 
    print "好的拜拜啦!" 
//11.这时bye函数调用完毕,从栈顶弹出

//12.最后又回到了函数greet,内部函数已经都调用完毕,故从greet返回。

这里的greet就是调用栈,所有函数调用都进入调用栈。不过调用栈可能很长,会占用大量的内存。

递归调用栈

比如下面用递归写的阶乘函数:

def fact(x):  //令 x = 3
    if x == 1;
    return 1
else:
    return x * fact(x-1)

在这里插入图片描述
在这里插入图片描述
注意,每个fact调用都有自己的x变量。在一个函数调用中不能访问另一个的x变量

### 递归算法执行过程中的变化 在 Java 中,每当发生方法调用时,都会创建一个新的帧(stack frame),该帧包含了当前方法的所有局部变量、参数以及返回地址等信息。对于递归而言,每次函数调用自己的行为实际上是在现有的基础上再增加一层新的帧。 #### 帧的生命周期 随着递归层次加深,每进入一次更深级别的递归调用,就相当于往顶添加了一个新元素;当达到最深层级并开始回溯时,则依次弹出这些帧直到完成整个递归流程[^1]。由于遵循后进先出 (LIFO) 的原则,在递归情况下表现为最近被调用的方法最先退出,这正好满足了递归逻辑的需求[^2]。 #### 图解递归调用过程中的变化 假设有一个简单的阶乘计算函数 `factorial(n)`: ```java public static long factorial(int n){ if (n == 0 || n == 1) return 1; else return n * factorial(n - 1); } ``` 如果调用 `factorial(3)` ,那么其对应的状态如下所示: | 调用顺序 | 当前处理的任务 | 内存储的内容 | |--------|---------------------|--------------------------| | 第一步 | 计算`factorial(3)` | `[n=3, 返回地址 -> 下次*result]` | | 第二步 | 计算`factorial(2)` | `[n=3], [n=2, 返回地址 -> 上层*n]` | | 第三步 | 计算`factorial(1)` | `[n=3], [n=2], [n=1, 结束条件命中->return 1]` | 一旦遇到终止条件 (`if`) 即可直接返回结果给上一级调用者,并逐步解除各层之间的关联关系直至最终得到完整的运算结果。 需要注意的是,虽然递归可以简化某些问题的理解和编码难度,但由于它依赖于频繁地入/出操作,因此可能会带来较大的空间消耗甚至引发溢出异常。所以在实际应用中应当谨慎评估是否适合采用递归来解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值