递归三种分类方法

文章目录

递归是编程语言中常见的算法技巧,但是递归名称很多,我整理了一下递归常见的三种分类法。

按调用"路数"分(最常见)

这是根据一个函数在递归时,会派生出几个"分身"来分类的。

A. 线性递归 (Linear Recursion)

  • 特点 :函数在递归阶段,只调用一次自己。
  • 长相
clike 复制代码
void linear(int n) {
    if (n <= 0) return;
    // 只调用一次自己
    linear(n - 1);
}
  • 理解 :这就像是一个单向链表,或者一根绳子,一头拉着一头,直到拉断(触底反弹)。
  • 例子:计算阶乘、遍历单链表。
  • 优化:这种递归可以直接改成循环!

B. 树形递归 (Tree Recursion)

*  特点 :函数在递归阶段,调用了多次 (通常是两次或以上)自己。

*  长相

clike 复制代码
void tree(int n) {
    if (n <= 1) return;
    // 调用两次自己,这就分叉了!
    tree(n - 1);
    tree(n - 2); 
}
  • 理解:这就像是二叉树的遍历,每走一步就分两叉,呈指数级爆炸增长。
  • 例子:斐波那契数列(朴素写法)、二叉树遍历。
  • 优化:这种递归有两种优化方案,使用显式栈(避免系统栈溢出)和记忆化搜索(加缓存)。但是要视情况而定:显式栈代码复杂;而多线程环境里的fork/join用的树形递归往往是拆分数据集,几乎没有重复的入参,加缓存没有用。

按"谁调用谁"分

这是根据函数调用的"人际关系"来分类的。

A. 直接递归 (Direct Recursion)

  • 特点 :函数 A 直接调用 自己(A)
  • 长相
clike 复制代码
void A() { 
    // ... 
    A(); // 我直接call我自己
}
  • 备注:这是我们最最常用的递归方式。

B. 间接递归 (Indirect Recursion)

  • 特点 :函数 A 调用函数 B ,函数 B 又反过来调用函数 A
  • 长相
clike 复制代码
void A() { 
    // ...
    B(); // 我让兄弟帮我干
}
    
void B() {
    // ...
    A(); // 兄弟又把活扔回给我
}
  • 理解:这就像是两个人互相踢皮球,直到把球踢烂(栈溢出)或者达成条件停止。

按"调用的位置"分(性能优化向)

这是你提到的尾递归所在的分类,也是性能优化的关键。

A. 头递归 (Head Recursion)

  • 特点 :先递归调用,拿到结果后,进行计算(或者说,递归调用在函数体的前面)。
  • 长相
clike 复制代码
int head(int n) {
    if (n == 0) return 0;
    // 先递归下去,等回来之后,还要做 +n 的操作
    return head(n - 1) + n; 
}
  • 缺点:必须把每一层的现场(比如这里的 n)都保存在栈里,等着"归"的时候用。容易栈溢出。

B. 尾递归 (Tail Recursion) ------ 你提到的那位

  • 特点 :递归调用是函数的最后一步操作。调用之后,函数不需要再做任何计算了,直接返回结果就行。
  • 长相
clike 复制代码
int tail(int n, int acc) {
    if (n == 0) return acc;
    // 计算已经在参数里做完了(acc + n),这里只是单纯的跳转
    return tail(n - 1, acc + n); 
}
  • 优点 :编译器可以进行尾调用优化 (TCO)。它不需要保留上一层的栈帧,直接把当前栈覆盖掉就行。这样,无论递归多少层,栈空间永远是 O(1) 的,不会栈溢出。

总结

分类维度 类型 关键特征
调用路数 线性递归 一层只调一次自己
树形递归 一层调多次自己
调用关系 直接递归 自己调自己
间接递归 你调我,我调你
调用位置 头递归 调完还要算
尾递归 调完直接返
相关推荐
wearegogog1235 小时前
基于 MATLAB 的卡尔曼滤波器实现,用于消除噪声并估算信号
前端·算法·matlab
一只小小汤圆5 小时前
几何算法库
算法
Evand J6 小时前
【2026课题推荐】DOA定位——MUSIC算法进行多传感器协同目标定位。附MATLAB例程运行结果
开发语言·算法·matlab
leo__5206 小时前
基于MATLAB的交互式多模型跟踪算法(IMM)实现
人工智能·算法·matlab
忆锦紫6 小时前
图像增强算法:Gamma映射算法及MATLAB实现
开发语言·算法·matlab
t198751286 小时前
基于自适应Chirplet变换的雷达回波微多普勒特征提取
算法
guygg886 小时前
采用PSO算法优化PID参数,通过调用Simulink和PSO使得ITAE标准最小化
算法
老鼠只爱大米7 小时前
LeetCode算法题详解 239:滑动窗口最大值
算法·leetcode·双端队列·滑动窗口·滑动窗口最大值·单调队列
mit6.8247 小时前
序列化|质数筛|tips|回文dp
算法
rgeshfgreh7 小时前
C++字符串处理:STL string终极指南
java·jvm·算法