← 返回内容列表

主定理到底在算什么:递归树一眼看懂

分享本文
主定理到底在算什么:递归树一眼看懂

主定理常被当成"背公式",其实它只是递归树求和的速查版。本文用一张递归树讲清:把每层代价加起来,看哪一层主导总复杂度,三种情况自然浮现。

递归树:T(n)=2T(n/2)+Θ(n) 每层代价都是 n层 0层 1层 2T(n)代价 cnT(n/2)cn/2T(n/2)cn/2本层总代价 = 2·(cn/2) = cnT(n/4)T(n/4)T(n/4)T(n/4)本层总代价 = 4·(cn/4) = cn叶子层:n^{log₂2}=n 个,每个 Θ(1) → 共 Θ(n)总代价 = 每层 cn × log₂n 层 + 叶子 cn = Θ(n log n)

图:归并排序的递归树——每层代价恒为 n,叠 log₂n 层得 Θ(n log n)

很多人学主定理(Master Theorem)靠背三句话,但一遇到变体就懵。其实主定理背后只有一个直觉:把递归展开成一棵树,把每一层的代价加起来,看哪一层最"重"。这一步叫递归树(recursion tree)

递归树怎么画

形如 T(n)=aT(n/b)+f(n)T(n)=aT(n/b)+f(n) 的递推:根代表原问题,代价 f(n)f(n);它分裂出 aa 个子问题,每个规模 n/bn/b;如此反复,直到规模降到 1(叶子)。第 ii 层有 aia^i 个节点,每个代价 f(n/bi)f(n/b^i),叶子层在第 logbn\log_b n 层。

总代价 = 各层代价之和

把每层总代价相加:层 ii 的总代价是 aif(n/bi)a^i\cdot f(n/b^i)。哪个量"主导"了这个和,复杂度就是它。这就自然引出主定理三情况——比较 f(n)f(n) 与临界值 nlogban^{\log_b a}(叶子总规模)。

参考代码:把递归树"加"出来验证

def tree_sum(n, a, b, f):
    total, lvl, size = 0, 0, n
    while size >= 1:
        total += (a ** lvl) * f(size)   # 第 lvl 层总代价
        size //= b
        lvl += 1
    return total

# 归并排序 a=2,b=2,f(n)=n:每层都是 n,叠 log n 层
print(tree_sum(8, 2, 2, lambda x: x))   # 40 = 8*log2(8) + 8 叶 ≈ Θ(n log n)

所以主定理不是魔法,它只是把"递归树求和"做成了分情况速查。理解了树,你就再也不用死记公式。

关联推荐

评论 (0)

正文划词可点「问萝卜特」——自动发评论并由 AI 回复

加载评论中…

主定理到底在算什么:递归树一眼看懂 - 用可视化演示,真正搞懂 AI 与编程 | 必学必会