递归与分治

一、概念与本质

1. 递归(Recursion)

  • 定义:一个函数直接 or 间接地调用自身。
  • 本质:一种控制流程(control flow),与迭代并列,是“实现手段”。
  • 必须满足:①基准情形(base case) ②递推关系(recursive case)。

2. 分治(Divide & Conquer)

  • 定义:算法设计范式,把规模为 n 的问题分成 k 个“互相独立、可独立求解”的子问题(通常 k≥2,且子问题规模 ≈ n/b),递归求解后再合并结果。
  • 本质:面向“问题分解”的顶层思想,与动态规划、贪心并列。

二、核心特征对比

维度递归分治
关键词自我调用、调用栈、基准条件拆分、独立、合并
是否要求“独立子问题”×√(子问题无重叠)
是否要求“合并结果”×√(Merge 步骤)
是否保证更小规模需要(否则无限递归)需要(否则无法收敛)
典型复杂度模型T(n)=T(n-1)+O(1) 等T(n)=aT(n/b)+f(n) 主定理
额外空间来源调用栈(最深=递归深度)同左,但可尾递归/迭代优化

三、执行流程拆解

1. 纯递归(以阶乘为例)

fact(n):
    if n==0: return 1          // base
    return n * fact(n-1)       // self-call,无“合并”

流程:一路压栈 → 到达 base → 一路弹栈返回乘积。

2. 分治(以归并排序为例)

mergeSort(A, l, r):
    if l==r: return            // 1. 基础规模
    mid = (l+r)//2
    mergeSort(A, l, mid)       // 2. 分
    mergeSort(A, mid+1, r)     // 2. 分
    merge(A, l, mid, r)        // 3. 合

流程:二分拆解 → 子序列有序 → 线性合并 → 向上返回。

四、复杂度示例

  • 阶乘递归:T(n)=T(n-1)+O(1) ⇒ Θ(n) 时间,Θ(n) 栈空间。
  • 归并分治:T(n)=2T(n/2)+Θ(n) ⇒ Θ(n log n) 时间,Θ(n) 额外空间(merge 数组 + log n 栈)。
  • 快速幂/二分搜索:T(n)=T(n/2)+Θ(1) ⇒ Θ(log n) 时间,Θ(log n) 栈(可尾递归消掉)。

五、代码骨架模板

1. 通用递归

def recursion(参数):
    if 基准情形: return 基准值
    缩小参数
    子结果 = recursion(缩小后参数)
    return 利用子结果构造当前结果

2. 通用分治

def divide_and_conquer(参数):
    if 规模足够小: return 蛮力解
    拆分成 k 个子问题
    for 子问题 in 子问题列表:
        子结果.append(divide_and_conquer(子问题))
    return merge(子结果列表)

其中 merge() 复杂度决定整个复杂度的 f(n) 项。

六、典型例子对号入座

  • 只用递归,不属于分治
    – 阶乘、斐波那契(朴素)、链表逆序打印、DFS 求连通块。
  • 分治 + 递归
    – 归并排序、快速排序、二分搜索、最大子段和(线段树/DC 法)、Strassen 矩阵乘、最近点对、FFT。

七、常见误区澄清

  1. “递归一定比分治慢” → 错误。递归只是实现手段,复杂度由算法本身决定。
  2. “分治必须二分” → 错误。可三分、四分(如 k-way 归并),只要子问题独立。
  3. “有了递归就不用迭代” → 错误。深递归可能栈溢出,可用显式栈或 bottom-up 消递归。
  4. “分治和动态规划都需要子问题” → 区别在“子问题是否重叠”。分治子问题独立,DP 子问题重叠且通常用记忆化/填表。

八、总结

  • 递归:手段 → 自我调用 → 关注“终止+递推式”。
  • 分治:思想 → 拆-治-合 → 关注“独立+合并”。
  • 关系:分治常常用递归落地,但递归也能干别的;分治可改写成迭代(bottom-up),只要你能手动维护栈/队列。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值