Go语言的递归函数

一、什么是递归函数?

递归函数 :

函数在自己的函数体中 调用自己

递归 =

  • 当前问题 拆成

  • 更小规模的同类问题

  • 直到一个 终止条件(base case)

少了终止条件,程序就会「无限套娃」直接栈溢出 。

二、Go 递归函数的基本结构

Go 中递归函数 和普通函数写法完全一样,没有任何特殊语法。

Go 复制代码
func f(...) 返回值 {
    // 1. 终止条件
    if 条件 {
        return 某个值
    }

    // 2. 递归调用
    return f(更小的问题)
}

三、最经典例子:阶乘(Factorial)

数学定义

n! = n × (n-1)!

0! = 1

Go 实现

Go 复制代码
func factorial(n int) int {
    if n == 0 {
        return 1 // 终止条件
    }
    return n * factorial(n-1)
}

调用

Go 复制代码
fmt.Println(factorial(5)) // 120

四、递归一定要有的 2 个要素

1. 终止条件(base case)

Go 复制代码
if n == 0 {
    return 1
}

否则会导致栈溢出

2. 规模缩小

Go 复制代码
factorial(n-1)

每次调用都 更接近终止条件

五、进阶点:斐波那契数列

定义

f(0) = 0

f(1) = 1

f(n) = f(n-1) + f(n-2)

Go 实现

Go 复制代码
//1、声明
func fib(n int) int {
    if n <= 1 {
        return n
    }
    return fib(n-1) + fib(n-2)
}


//2、调用
fmt.Println(fib(6)) // 输出8

注意 :

这个写法在 n 大时 性能很差(重复计算)

六、递归在 Go 中的常见使用场景

1. 树 / 目录结构遍历

Go 复制代码
type Node struct {
    Val      int
    Children []*Node
}

func dfs(node *Node) {
    if node == nil {
        return
    }
    fmt.Println(node.Val)
    for _, child := range node.Children {
        dfs(child)
    }
}

2. 文件系统递归遍历

Go 复制代码
func walkDir(path string) {
    files, _ := os.ReadDir(path)
    for _, f := range files {
        fullPath := filepath.Join(path, f.Name())
        if f.IsDir() {
            walkDir(fullPath)
        } else {
            fmt.Println(fullPath)
        }
    }
}

3. 分治算法

  • 快速排序

  • 归并排序

  • 二分查找

七、递归 vs for 循环(Go 实战视角)

对比点 递归 循环
代码可读性 ⭐⭐⭐⭐ ⭐⭐⭐
写起来 简洁 稍繁琐
性能 一般 ⭐⭐⭐⭐
栈风险 有 无

Go 实战建议:

  • 层级浅、逻辑清晰 用递归

  • 层级深、频繁调用 用循环或显式栈

八、Go 的一个小坑:没有尾递归优化

Go 不保证尾递归优化(不像某些函数式语言)

尾递归示例(但 Go 依然会压栈)

Go 复制代码
func sum(n, acc int) int {
    if n == 0 {
        return acc
    }
    return sum(n-1, acc+n)
}

即使是尾递归,
栈深度依然增长,大数据量要小心。

相关推荐
武子康10 小时前
MultiNet6 空闲崩溃:`EXCVADDR=0x8` 后又出现 `CORRUPT HEAP`
人工智能·后端·agent
开开心心_Every10 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea
chenbingjie_c10 小时前
C++ 多态完全指南:从虚函数重写到虚函数表原理
开发语言·c++
吴卫斌10 小时前
定投ETF实战指南(四):行业/主题ETF——定投的“进攻端“
开发语言·python·股票·量化
武子康11 小时前
MultiNet7 每轮都 clean,ESP32-P4 内存为什么还在掉?
人工智能·后端·agent
超级架构师11 小时前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
陈随易12 小时前
AI 运维服务器,安全又可靠的方法
前端·后端·程序员
叼烟扛炮12 小时前
Linux 学习笔记(四十三):网络编程进阶——自定义协议解决 TCP 粘包与守护进程
linux·开发语言·网络·笔记·tcp/ip
LMT流氓兔13 小时前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
专注仿真13 小时前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法