当前位置: 首页 > news >正文

第2章算法分析:大O符号的定义和性质

2.3 大 O 符号

2.3.1 大 O 符号的定义

大 O 符号(Big O notation),又称为渐近符号,是用于描述函数渐近行为的数学符号。更确切地说,它是用另一个(通常更简单的)函数来描述一个函数数量级的渐近上界

大 O 符号是由德国数论学家保罗·巴赫曼在其1892年的著作《解析数论》(Analytische Zahlentheorie)首先引入的。之后经另一位德国数论学家爱德蒙·兰道的著作得到推广,因此它有时又称为兰道符号(Landau symbols)。代表“order of …”(……阶)的大 O,最初是一个大写希腊字母“Ο”(omicron),现今用的是大写英文字母“O”。

大 O 符号的本质是函数渐近行为的极限描述,其形式化定义:

给定两个定义在实数某子集上的关于 xxx 的函数 f(x)f(x)f(x)g(x)g(x)g(x) ,当 xxx 趋近于无穷大时,存在正实数 MMM ,使得对于所有充分大的 xxx ,都有f(x)f(x)f(x) 的绝对值小于等于 M×g(x)M\times g(x)M×g(x) 的绝对值,那么我们就可以说,当 x→∞x\to\inftyx 时,
f(x)=O(g(x)) f(x)=O(g(x)) f(x)=O(g(x))
也就是说,假如存在正实数 MMM 和实数 x0x_0x0 ,使得对于所有的 x≥x0x\ge x_0xx0 ,均有:∣f(x)∣≤M∣g(x)∣|f(x)|\le M|g(x)|f(x)Mg(x) 成立,我们就可以认为 f(x)=O(g(x))f(x)=O(g(x))f(x)=O(g(x)) 。在很多情况下,会省略“当 xxx 趋近于无限大时”这个前提。

上述定义,用极限来表示:
当且仅当 lim⁡x→∞∣f(x)g(x)∣<∞ 时,有 f(x)=O(g(x)) 当且仅当~\lim_{x\to\infty}\left|\frac{f(x)}{g(x)}\right|\lt\infty~时,有~f(x)=O(g(x)) 当且仅当 xlimg(x)f(x)< 时,有 f(x)=O(g(x))
也就是,当 x→∞x\to\inftyx 时,f(x)g(x)\frac{f(x)}{g(x)}g(x)f(x) 有上界,极限值为有限常数或未达无穷大。

例 1: 证明 T(n)=3n2+5n+2T(n)=3n^2 + 5n + 2T(n)=3n2+5n+2O(n2)O(n^2)O(n2)

证明:

lim⁡n→∞3n2+5n+2n2=lim⁡n→∞(3+5n+2n2)=3(有限正常数) \lim_{n\to\infty}\frac{3n² + 5n + 2}{n²}=\lim_{n\to\infty}\left(3 + \frac{5}{n} + \frac{2}{n^2}\right) = 3 (有限正常数) nlimn23n2+5n+2=nlim(3+n5+n22)=3(有限正常数)
因为极限存在且为有限值,所以 T(n)=O(n2)T(n) = O(n^2)T(n)=O(n2)

2.3.2 大 O 符号的性质

以下是大 O 符号的主要性质及其证明。证明中假设所有函数定义在自然数上,且 f(n)f(n)f(n) 非零(或仅在有限点为零)。

性质 1:(自反性)对于任意函数 f(n)f(n)f(n),有 f(n)=O(f(n))f(n) = O(f(n))f(n)=O(f(n))

证明:

取常数 c=1c = 1c=1n0=1n_0 = 1n0=1。则对于所有 n≥n0n \geq n_0nn0,有:∣f(n)∣≤1⋅∣f(n)∣|f(n)| \leq 1 \cdot |f(n)|f(n)1f(n) 。根据大 O 定义,这直接表明 f(n)=O(f(n))f(n) = O(f(n))f(n)=O(f(n))

性质 2:(传递性)如果 f(n)=O(g(n))f(n) = O(g(n))f(n)=O(g(n))g(n)=O(h(n))g(n) = O(h(n))g(n)=O(h(n)),则 f(n)=O(h(n))f(n) = O(h(n))f(n)=O(h(n))

证明:

f(n)=O(g(n))f(n) = O(g(n))f(n)=O(g(n)),存在常数 c1>0c_1 > 0c1>0n1n_1n1 使得对于所有 n≥n1n \geq n_1nn1,有:∣f(n)∣≤c1⋅∣g(n)∣|f(n)| \leq c_1 \cdot |g(n)|f(n)c1g(n)

g(n)=O(h(n))g(n) = O(h(n))g(n)=O(h(n)),存在常数 c2>0c_2 > 0c2>0n2n_2n2 使得对于所有 n≥n2n \geq n_2nn2,有:∣g(n)∣≤c2⋅∣h(n)∣|g(n)| \leq c_2 \cdot |h(n)|g(n)c2h(n)

n0=max⁡(n1,n2)n_0 = \max(n_1, n_2)n0=max(n1,n2)c=c1⋅c2c = c_1 \cdot c_2c=c1c2。则对于所有 n≥n0n \geq n_0nn0,有:
∣f(n)∣≤c1⋅∣g(n)∣≤c1⋅(c2⋅∣h(n)∣)=(c1c2)⋅∣h(n)∣=c⋅∣h(n)∣. |f(n)| \leq c_1 \cdot |g(n)| \leq c_1 \cdot (c_2 \cdot |h(n)|) = (c_1 c_2) \cdot |h(n)| = c \cdot |h(n)|. f(n)c1g(n)c1(c2h(n))=(c1c2)h(n)=ch(n)∣.
因此, f(n)=O(h(n))f(n) = O(h(n))f(n)=O(h(n)).

性质 3:(常数倍性质)如果 f(n)=O(g(n))f(n) = O(g(n))f(n)=O(g(n))kkk 是一个常数(即 k∈R∖{0}k \in \mathbb{R} \setminus \{0\}kR{0},但 k=0k = 0k=0 时平凡成立),则 k⋅f(n)=O(g(n))k \cdot f(n) = O(g(n))kf(n)=O(g(n))

证明:

f(n)=O(g(n))f(n) = O(g(n))f(n)=O(g(n)),存在常数 c1>0c_1 > 0c1>0n1n_1n1 使得对于所有 n≥n1n \geq n_1nn1,有:∣f(n)∣≤c1⋅∣g(n)∣.|f(n)| \leq c_1 \cdot |g(n)|.f(n)c1g(n)∣.

c=∣k∣⋅c1c = |k| \cdot c_1c=kc1n0=n1n_0 = n_1n0=n1。则对于所有 n≥n0n \geq n_0nn0,有:∣k⋅f(n)∣=∣k∣⋅∣f(n)∣≤∣k∣⋅(c1⋅∣g(n)∣)=(∣k∣c1)⋅∣g(n)∣=c⋅∣g(n)∣|k \cdot f(n)| = |k| \cdot |f(n)| \leq |k| \cdot (c_1 \cdot |g(n)|) = (|k| c_1) \cdot |g(n)| = c \cdot |g(n)|kf(n)=kf(n)k(c1g(n))=(kc1)g(n)=cg(n)

因此, k⋅f(n)=O(g(n))k \cdot f(n) = O(g(n))kf(n)=O(g(n)).

性质 4:(和的性质)如果 f1(n)=O(g1(n))f_1(n) = O(g_1(n))f1(n)=O(g1(n))f2(n)=O(g2(n))f_2(n) = O(g_2(n))f2(n)=O(g2(n)),则 f1(n)+f2(n)=O(max⁡(∣g1(n)∣,∣g2(n)∣))f_1(n) + f_2(n) = O(\max(|g_1(n)|, |g_2(n)|))f1(n)+f2(n)=O(max(g1(n),g2(n)))。更一般地,f1(n)+f2(n)=O(∣g1(n)∣+∣g2(n)∣)f_1(n) + f_2(n) = O(|g_1(n)| + |g_2(n)|)f1(n)+f2(n)=O(g1(n)+g2(n)),且当 g1(n)g_1(n)g1(n)g2(n)g_2(n)g2(n) 渐近非负时,可简化为 O(max⁡(∣g1(n)∣,∣g2(n)∣))O(\max(|g_1(n)|, |g_2(n)|))O(max(g1(n),g2(n)))

证明:

f1(n)=O(g1(n))f_1(n) = O(g_1(n))f1(n)=O(g1(n)),存在常数 c1>0c_1 > 0c1>0n1n_1n1 使得对于所有 n≥n1n \geq n_1nn1,有:∣f1(n)∣≤c1⋅∣g1(n)∣|f_1(n)| \leq c_1 \cdot |g_1(n)|f1(n)c1g1(n) .

f2(n)=O(g2(n))f_2(n) = O(g_2(n))f2(n)=O(g2(n)),存在常数 c2>0c_2 > 0c2>0n2n_2n2 使得对于所有 n≥n2n \geq n_2nn2,有:∣f2(n)∣≤c2⋅∣g2(n)∣|f_2(n)| \leq c_2 \cdot |g_2(n)|f2(n)c2g2(n)

n0=max⁡(n1,n2)n_0 = \max(n_1, n_2)n0=max(n1,n2)c=c1+c2c = c_1 + c_2c=c1+c2。定义 g(n)=max⁡(∣g1(n)∣,∣g2(n)∣)g(n) = \max(|g_1(n)|, |g_2(n)|)g(n)=max(g1(n),g2(n))。注意到对于所有 nnn,有 ∣g1(n)∣≤g(n)|g_1(n)| \leq g(n)g1(n)g(n)∣g2(n)∣≤g(n)|g_2(n)| \leq g(n)g2(n)g(n)。则对于所有 n≥n0n \geq n_0nn0,有:
∣f1(n)+f2(n)∣≤∣f1(n)∣+∣f2(n)∣≤c1⋅∣g1(n)∣+c2⋅∣g2(n)∣≤c1⋅g(n)+c2⋅g(n)=(c1+c2)⋅g(n)=c⋅g(n) |f_1(n) + f_2(n)| \leq |f_1(n)| + |f_2(n)| \leq c_1 \cdot |g_1(n)| + c_2 \cdot |g_2(n)| \leq c_1 \cdot g(n) + c_2 \cdot g(n) = (c_1 + c_2) \cdot g(n) = c \cdot g(n) f1(n)+f2(n)f1(n)+f2(n)c1g1(n)+c2g2(n)c1g(n)+c2g(n)=(c1+c2)g(n)=cg(n)
因此, f1(n)+f2(n)=O(g(n))=O(max⁡(∣g1(n)∣,∣g2(n)∣))f_1(n) + f_2(n) = O(g(n)) = O(\max(|g_1(n)|, |g_2(n)|))f1(n)+f2(n)=O(g(n))=O(max(g1(n),g2(n)))

此外,因为 ∣g1(n)∣+∣g2(n)∣≤2max⁡(∣g1(n)∣,∣g2(n)∣)|g_1(n)| + |g_2(n)| \leq 2 \max(|g_1(n)|, |g_2(n)|)g1(n)+g2(n)2max(g1(n),g2(n)),所以 f1(n)+f2(n)=O(∣g1(n)∣+∣g2(n)∣)f_1(n) + f_2(n) = O(|g_1(n)| + |g_2(n)|)f1(n)+f2(n)=O(g1(n)+g2(n)) 也成立。

性质 5:(乘积性质)如果 f1(n)=O(g1(n))f_1(n) = O(g_1(n))f1(n)=O(g1(n))f2(n)=O(g2(n))f_2(n) = O(g_2(n))f2(n)=O(g2(n)),则 f1(n)⋅f2(n)=O(g1(n)⋅g2(n))f_1(n) \cdot f_2(n) = O(g_1(n) \cdot g_2(n))f1(n)f2(n)=O(g1(n)g2(n))

证明:

f1(n)=O(g1(n))f_1(n) = O(g_1(n))f1(n)=O(g1(n)),存在常数 c1>0c_1 > 0c1>0n1n_1n1 使得对于所有 n≥n1n \geq n_1nn1,有:∣f1(n)∣≤c1⋅∣g1(n)∣|f_1(n)| \leq c_1 \cdot |g_1(n)|f1(n)c1g1(n)。同理可得:∣f2(n)∣≤c2⋅∣g2(n)∣|f_2(n)| \leq c_2 \cdot |g_2(n)|f2(n)c2g2(n)

n0=max⁡(n1,n2)n_0 = \max(n_1, n_2)n0=max(n1,n2)c=c1⋅c2c = c_1 \cdot c_2c=c1c2。则对于所有 n≥n0n \geq n_0nn0,有:∣f1(n)⋅f2(n)∣=∣f1(n)∣⋅∣f2(n)∣≤(c1⋅∣g1(n)∣)⋅(c2⋅∣g2(n)∣)=(c1c2)⋅∣g1(n)⋅g2(n)∣=c⋅∣g1(n)⋅g2(n)∣|f_1(n) \cdot f_2(n)| = |f_1(n)| \cdot |f_2(n)| \leq (c_1 \cdot |g_1(n)|) \cdot (c_2 \cdot |g_2(n)|) = (c_1 c_2) \cdot |g_1(n) \cdot g_2(n)| = c \cdot |g_1(n) \cdot g_2(n)|f1(n)f2(n)=f1(n)f2(n)(c1g1(n))(c2g2(n))=(c1c2)g1(n)g2(n)=cg1(n)g2(n)

因此, f1(n)⋅f2(n)=O(g1(n)⋅g2(n))f_1(n) \cdot f_2(n) = O(g_1(n) \cdot g_2(n))f1(n)f2(n)=O(g1(n)g2(n)).

性质 6:(多项式性质)如果 f(n)f(n)f(n) 是一个 kkk 次多项式,即 f(n)=aknk+ak−1nk−1+⋯+a0f(n) = a_k n^k + a_{k-1} n^{k-1} + \cdots + a_0f(n)=aknk+ak1nk1++a0(其中 ak≠0a_k \neq 0ak=0),则 f(n)=O(nk)f(n) = O(n^k)f(n)=O(nk)

证明:

对于足够大的 nnn(例如 n≥1n \geq 1n1),有 ∣ni∣≤∣nk∣|n^i| \leq |n^k|nink 对所有 i≤ki \leq kik 成立。因此:
∣f(n)∣≤∣ak∣∣nk∣+∣ak−1∣∣nk−1∣+⋯+∣a0∣≤∣ak∣∣nk∣+∣ak−1∣∣nk∣+⋯+∣a0∣∣nk∣=(∑i=0k∣ai∣)∣nk∣ |f(n)| \leq |a_k| |n^k| + |a_{k-1}| |n^{k-1}| + \cdots + |a_0| \leq |a_k| |n^k| + |a_{k-1}| |n^k| + \cdots + |a_0| |n^k| = \left( \sum_{i=0}^{k} |a_i| \right) |n^k| f(n)ak∣∣nk+ak1∣∣nk1++a0ak∣∣nk+ak1∣∣nk++a0∣∣nk=(i=0kai)nk
c=∑i=0k∣ai∣c = \sum_{i=0}^{k} |a_i|c=i=0kain0=1n_0 = 1n0=1。则对于所有 n≥n0n \geq n_0nn0,有 ∣f(n)∣≤c⋅∣nk∣|f(n)| \leq c \cdot |n^k|f(n)cnk,所以 f(n)=O(nk)f(n) = O(n^k)f(n)=O(nk).

性质 7:(对数性质)对于底数 b>1b > 1b>1a>0a > 0a>0,有 log⁡bn=O(log⁡2n)\log_b n = O(\log_2n)logbn=O(log2n),且更一般地,(log⁡bn)a=O(nϵ)(\log_b n)^a = O(n^\epsilon)(logbn)a=O(nϵ) 对于任意 ϵ>0\epsilon > 0ϵ>0(即对数函数增长慢于任何正幂函数)。

证明:

  • 部分 1: log⁡bn=O(log⁡n)\log_b n = O(\log n)logbn=O(logn)

    由对数换底公式,log⁡bn=ln⁡nln⁡b\log_b n = \frac{\ln n}{\ln b}logbn=lnblnn。取 c=1∣ln⁡b∣c = \frac{1}{|\ln b|}c=lnb1(因为 b>1b > 1b>1,所以 ln⁡b>0\ln b > 0lnb>0) 和 n0=1n_0 = 1n0=1。则对于所有 n≥n0n \geq n_0nn0,有:
    ∣log⁡bn∣=∣ln⁡nln⁡b∣=∣ln⁡n∣∣ln⁡b∣≤c⋅∣ln⁡n∣ |\log_b n| = \left| \frac{\ln n}{\ln b} \right| = \frac{|\ln n|}{|\ln b|} \leq c \cdot |\ln n| logbn=lnblnn=lnblnnclnn
    因此, log⁡bn=O(log⁡n)\log_b n = O(\log n)logbn=O(logn)(这里 log⁡n\log nlogn 表示自然对数)。

  • 部分 2: (log⁡bn)a=O(nϵ)(\log_b n)^a = O(n^\epsilon)(logbn)a=O(nϵ) 对于任意 ϵ>0\epsilon > 0ϵ>0

    这可以通过极限或 L’Hôpital 法则证明。考虑极限:lim⁡n→∞(log⁡bn)anϵ\lim_{n \to \infty} \frac{(\log_b n)^a}{n^\epsilon}limnnϵ(logbn)a

    t=log⁡bnt = \log_b nt=logbn,则 n=btn = b^tn=bt,当 n→∞n \to \inftynt→∞t \to \inftyt,极限变为:
    lim⁡t→∞ta(bt)ϵ=lim⁡t→∞tabϵt. \lim_{t \to \infty} \frac{t^a}{(b^t)^\epsilon} = \lim_{t \to \infty} \frac{t^a}{b^{\epsilon t}}. tlim(bt)ϵta=tlimbϵtta.
    由于指数函数增长快于多项式函数,该极限为 0。因此,存在 n0n_0n0 使得对于所有 n≥n0n \geq n_0nn0,有 (log⁡bn)anϵ≤1\frac{(\log_b n)^a}{n^\epsilon} \leq 1nϵ(logbn)a1,即 ∣(log⁡bn)a∣≤1⋅∣nϵ∣|(\log_b n)^a| \leq 1 \cdot |n^\epsilon|(logbn)a1nϵ。所以 (log⁡bn)a=O(nϵ)(\log_b n)^a = O(n^\epsilon)(logbn)a=O(nϵ).

注意:

  • 大 O 符号不具有对称性:即 f(n)=O(g(n))f(n) = O(g(n))f(n)=O(g(n)) 不一定意味着 g(n)=O(f(n))g(n) = O(f(n))g(n)=O(f(n))。如果两者同时成立,则记作 f(n)=Θ(g(n))f(n) = \Theta(g(n))f(n)=Θ(g(n))(Theta 符号),表示 fffggg 有相同的渐近增长率。

  • 大 O 符号关注上界,且忽略常数因子和低阶项,这使其适用于描述大规模输入下的性能。

  • 不要写成 T(n)=O(2n2)T(n)=O(2n^2)T(n)=O(2n2)T(n)=O(n2+n)T(n)=O(n^2+n)T(n)=O(n2+n) 。这两种的正确表示是 T(n)=O(n2)T(n)=O(n^2)T(n)=O(n2)

  • 不表示 T(n)≤O(f(n))T(n)\le O(f(n))T(n)O(f(n)) ,因为对大 O 记号的定义中已经隐含了不等关系。

  • T(n)≥O(f(n))T(n)\ge O(f(n))T(n)O(f(n)) 的表示是错误的,没有意义。

大 O 符号体现了对函数总体渐进趋势的关注和刻画,在后续进行算法时间复杂度和空间复杂度分析中将大显身手。

以上一直在书写大 O 符号,如果用口语表达,怎么读?以 O(n)O(n)O(n) 为例,可以读作“大 O n”,也可以读作 “O n”。

http://www.lryc.cn/news/603142.html

相关文章:

  • 第17章——多元函数积分学的预备知识
  • golang--通道和锁
  • springboot集成deepseek
  • c++: 尾置返回类型(Trailing Return Type)
  • 【MySQL基础篇】:MySQL常用数据类型的选择逻辑与正确使用
  • 前段面试题新版
  • 【分布式版本控制系统】Git的使用
  • 完整复现cacti的RCE
  • 【Python】自动化GIT提交
  • Linux:线程同步与线程互斥
  • SpringBoot原理揭秘--自动装配
  • LeetCode 2044.统计按位或能得到最大值的子集数目:二进制枚举/DFS回溯(剪枝)
  • Leaflet 综合案例 - 路径规划
  • 3. 卷积网络代码参数解读分析
  • 前端高级综合搜索组件 SearchBox 使用详解!
  • 4.DRF 认证--Authentication4.DRF 认证--Authentication
  • django ManyToManyField 如何添加数据
  • python-内存管理
  • Kubernetes --存储入门
  • 基于FPGA和DDS原理的任意波形发生器(含仿真)
  • 做了一款小而美的本地校验器
  • 【0基础PS】PS工具详解--选择工具--对象选择工具
  • 天学网面试 —— 中级前端开发岗位
  • B树、B+树、红黑树区别
  • 安宝特案例丨AR+AI+SOP?3大技术融合革新军工航天领域
  • windows部署ACE-Step记录
  • 语音识别数据增强
  • Redis实战(3)-- 高级数据结构zset
  • C++现代Redis客户端库redis-plus-plus详解
  • 第四章:分析 Redis 性能高原因和核心字符串类型命令