🔄 递归函数详解

动态互动演示 - 基于谭浩强《C 程序设计》经典例题

1. 递归函数的三要素

📌 什么是递归?

递归是指函数在定义中调用自身的过程。核心思想是将复杂问题分解为规模更小但结构相似的子问题。

递归三要素

🎯 要素 1:基准情形 (Base Case)

递归必须有终止条件,否则会造成无限递归,导致栈溢出。

if (n == 0) // 基准情形 return 1;

🎯 要素 2:递归调用 (Recursive Call)

函数在定义中调用自身,每次调用都向基准情形靠近。

return n * factorial(n - 1); // 递归调用

🎯 要素 3:状态变化 (State Change)

每次递归调用时,问题规模必须减小。

factorial(5) → factorial(4) → factorial(3) → factorial(2) → factorial(1) ↓ 规模减小
💡 提示:缺少任何一个要素,递归都无法正常工作!

递归执行过程可视化

🎬 演示递归调用过程

1
2
3
4
5
> 点击"开始演示"查看递归过程...

2. 阶乘计算递归演示

📐 数学定义

n! = n × (n-1) × (n-2) × ... × 1

递归定义:n! = n × (n-1)!,其中 0! = 1, 1! = 1

代码实现

long factorial_recursive(int n) { // 基准情形 if (n == 0 || n == 1) return 1; // 递归调用 return n * factorial_recursive(n - 1); }

互动演示

🧮 阶乘计算器

> 等待计算...

📊 递归树展开

3. 斐波那契数列递归演示

📐 数学定义

F(1) = 1, F(2) = 1

F(n) = F(n-1) + F(n-2) (n ≥ 3)

数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55...

代码实现

int fibonacci_recursive(int n) { // 基准情形 if (n <= 2) return 1; // 递归调用 return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2); }
⚠️ 注意:递归版斐波那契存在大量重复计算,效率较低。实际应用中建议使用迭代版或记忆化递归。

互动演示

🔢 斐波那契计算器

> 等待计算...

🌳 递归树可视化

4. 汉诺塔问题递归演示

📜 问题描述

将 n 个盘子从 A 柱移到 C 柱,每次只能移动一个盘子,大盘子不能放在小盘子上面。

代码实现

int move_count = 0; void hanoi(int n, char from, char to, char aux) { // 基准情形 if (n == 1) { move_count++; printf("第%d步:%c → %c\n", move_count, from, to); return; } // 递归步骤 hanoi(n - 1, from, aux, to); move_count++; printf("第%d步:%c → %c\n", move_count, from, to); hanoi(n - 1, aux, to, from); }

互动演示

🏛️ 汉诺塔动画

> 点击"开始移动"查看步骤...

5. 最大公约数递归演示

📐 辗转相除法(欧几里得算法)

gcd(m, n) = gcd(n, m % n)

当 n = 0 时,返回 m

代码实现

int gcd_recursive(int m, int n) { // 基准情形 if (n == 0) return m; // 递归调用 return gcd_recursive(n, m % n); }

互动演示

🔢 最大公约数计算器

> 等待计算...

📊 递归过程展示

6. 递归 vs 迭代 性能对比

📊 对比表格

特性 递归 迭代
代码简洁性 ⭐⭐⭐⭐⭐ 简洁优雅 ⭐⭐⭐ 相对冗长
可读性 ⭐⭐⭐⭐ 接近数学定义 ⭐⭐⭐ 需要理解循环
内存使用 ⭐⭐ 占用栈空间 ⭐⭐⭐⭐⭐ 内存效率高
执行效率 ⭐⭐⭐ 可能有重复计算 ⭐⭐⭐⭐⭐ 通常更高效

性能测试

⚡ 斐波那契性能对比

0ms 递归版
0ms 迭代版
> 点击"运行测试"查看性能对比...
💡 优化建议:对于斐波那契数列,可以使用记忆化递归动态规划来优化性能!

7. 递归知识测试

0/5
第 1 题:递归函数必须具备的要素是?
A. 只需要递归调用
B. 基准情形 + 递归调用 + 状态变化
C. 只需要基准情形
D. 必须有循环结构
第 2 题:以下哪个函数可能导致栈溢出?
A. 有基准情形的递归
B. 没有终止条件的递归
C. 迭代函数
D. 以上都不是
第 3 题:斐波那契数列 F(6) 的值是多少?
A. 5
B. 6
C. 8
D. 13
第 4 题:3 个盘子的汉诺塔问题最少需要多少步?
A. 3 步
B. 7 步
C. 5 步
D. 9 步
第 5 题:递归和迭代的关系是?
A. 递归一定比迭代慢
B. 递归一定比迭代快
C. 可以相互转换,各有优劣
D. 完全无关