C#递归函数怎么写?简单教程分享
作者:RiverSoul
时间:2026-02-23
浏览:4
递归函数必须有前置终止条件,否则会无限调用导致栈溢出;C#栈空间有限(约1MB),递归过深即崩溃;终止判断须置于函数开头,不可依赖后续计算。
本文目录
递归函数必须有前置终止条件,否则会无限调用导致栈溢出;C#栈空间有限(约1MB),递归过深即崩溃;终止判断须置于函数开头,不可依赖后续计算。

递归函数必须有明确的终止条件
没有终止条件的递归会无限调用,最终导致 StackOverflowException。C# 对栈深度有限制(通常约 1MB 栈空间),哪怕逻辑看似简单,一旦递归层级过深就崩溃。
写递归前先问自己:什么情况下该停止?这个判断必须放在函数开头,且不依赖后续计算。
- 错误写法:
if (n == 0) return 1;放在最后,中间还做了n * Factorial(n-1)—— 此时已发生一次调用,没防住越界 - 正确写法:先检查
n <= 1,立刻返回,再处理递归分支 - 对用户输入要额外校验:
if (n < 0) throw new ArgumentException("n must be non-negative");
阶乘是最典型的 C# 递归示例
它直观体现「问题分解为相同结构的子问题」:求 n! 就是 n × (n−1)!,而 (n−1)! 又可继续拆解。
public static long Factorial(int n)
{
if (n < 0) throw new ArgumentException("n must be non-negative");
if (n <= 1) return 1; // 终止条件
return n * Factorial(n - 1); // 递归调用
}注意:long 类型仅支持到 20! 左右;超过需用 BigInteger。另外,Factorial(10000) 会直接栈溢出——这不是算法错,是 C# 运行时限制。
避免重复计算:斐波那契递归的坑
直接写 Fib(n) = Fib(n-1) + Fib(n-2) 看似自然,但时间复杂度是 O(2^n),因为大量子问题被反复计算。
- 调用
Fib(5)时,Fib(3)被算两次,Fib(2)被算三次 Fib(45)在普通机器上就要等好几秒,Fib(50)更久- 这不是递归本身的问题,而是没做记忆化(memoization)
若坚持递归,应缓存结果:
private static readonly Dictionary_memo = new(); public static long Fib(int n) { if (n < 0) throw new ArgumentException("n must be non-negative"); if (n <= 1) return n; if (_memo.TryGetValue(n, out var value)) return value; value = Fib(n - 1) + Fib(n - 2); _memo[n] = value; return value; }
递归替代方案:什么时候该用循环
所有递归都能转成迭代(用栈或队列模拟调用栈),尤其当问题天然线性(如遍历树的深度优先)、或数据量大、或需精确控制内存时,迭代更稳。
- 文件系统遍历:递归易因路径过深崩溃,
Directory.GetFiles(path, "*", SearchOption.AllDirectories)内部是迭代实现 - 解析嵌套 JSON 或 XML:用栈比递归更易中断、调试和限深
- 尾递归优化?C# 编译器不支持自动尾调用优化(Tail Call Optimization),即使写成尾递归形式(最后一个操作是调用自身),仍会压栈
真正需要递归的场景其实不多:语法树解析、回溯算法(如八皇后)、分治(归并排序的合并逻辑)——这些结构天然递归,硬改成迭代反而难读难维护。
作者最新文章
漫蛙漫画app下载安装最新版本
2026-10-13 13:19
漫蛙漫画官网入口链接
2026-10-13 13:19
漫蛙2漫画APP最新版本下载免费安装
2026-10-13 13:17
漫蛙漫画官网正版登录入口
2026-10-13 13:15
Windows安装Docker教程:启用WSL2并运行第一个容器验证
2026-10-08 17:47
上一篇:
Lumia需订阅Office 365
下一篇:
PPT平滑切换设置方法及动画制作技巧
热门文章
更多
精品专题
更多
Mac软件
更多
WINDOWS
更多










































