算法分析基本概念

为什么需要复杂度分析

当我们评估一个算法的执行效率的是,有一种很直观的方法叫事后统计法,就是通过各种检测,得出某个算法实际的运行时间,但是这种方法有很多局限性:

  • 测试结果非常依赖测试环境
  • 测试结果受数据规模影响很大

所以我们需要一个不用具体的数据来测试,就可以粗略估计算法的执行效率的方法

四个定义:

  • 如果存在正常数 c {c} c n 0 {n_0} n0,使得当 N ≥ n 0 {N\geq n_0} Nn0时, T ( N ) ≤ c f ( N ) {T(N) \le cf(N)} T(N)cf(N),则记为 T ( N ) = O ( f ( n ) ) {T(N) = O(f(n))} T(N)=O(f(n))上界
  • 如果存在正常数 c {c} c n 0 {n_0} n0,使得当 N ≥ n 0 {N\geq n_0} Nn0时, T ( N ) ≥ c f ( N ) {T(N) \geq cf(N)} T(N)cf(N),则记为 T ( N ) = Ω ( f ( n ) ) {T(N) = \Omega(f(n))} T(N)=Ω(f(n))下界
  • T ( N ) = Θ ( h ( N ) ) {T(N)=\Theta(h(N))} T(N)=Θ(h(N))当且仅当 T ( N ) = O ( h ( N ) ) {T(N) = O(h(N))} T(N)=O(h(N)) T ( N ) = Ω ( h ( N ) ) {T(N) = \Omega(h(N))} T(N)=Ω(h(N))紧确界
  • 如果对每一正常数 c {c} c都存在常数 n 0 {n_0} n0,使得当 N > n 0 {N>n_0} N>n0时, T ( N ) < c p ( N ) {T(N)T(N)<cp(N),则 T ( N ) = o ( p ( N ) ) {T(N) = o(p(N))} T(N)=o(p(N))

给定的两个函数,通常会存在一些点,在这些点上一个函数的值小于另一个函数,所以单纯的比较两个函数的大小是没有意义的,我们比较的是他们的相对增长率,在描述的时候,应该说一个算法复杂度是“大O…级的

重要结论

  • 如果 T 1 ( N ) = O ( f ( N ) ) {T_1(N) = O(f(N))} T1(N)=O(f(N)) T 2 ( N ) = O ( g ( N ) ) {T_2(N) = O(g(N))} T2(N)=O(g(N)),那么
    1. T 1 ( N ) + T 2 ( N ) = O ( f ( N ) + g ( N ) ) {T_1(N)+T_2(N) = O(f(N)+g(N))} T1(N)+T2(N)=O(f(N)+g(N))(直观和非直观的可以写成 m a x ( O ( f ( N ) , O ( g ( N ) ) ) {max(O(f(N),O(g(N)))} max(O(f(N),O(g(N)))
    2. T 1 ( N ) ∗ T 2 ( N ) = O ( f ( N ) ∗ g ( N ) ) {T_1(N)*T_2(N) = O(f(N)*g(N))} T1(N)T2(N)=O(f(N)g(N))
  • 如果 T ( N ) {T(N)} T(N)是一个 k {k} k次多项式,则 T ( N ) = Θ ( N k ) {T(N) = \Theta(N^k)} T(N)=Θ(Nk)
  • 对于任意常数 k {k} k l o g k N = O ( N ) {log^kN = O(N)} logkN=O(N),它告诉我们对数增长的非常缓慢

注意不要写成 f ( N ) ≤ O ( g ( N ) ) {f(N)\le O(g(N))} f(N)O(g(N)),因为大 O {O} O表示法已经包含了小于等于的意思,应该直接用 f ( N ) = O ( g ( N ) ) {f(N)=O(g(N))} f(N)=O(g(N))

模型

在我们的计算模型中:

  • 机器指令顺序执行
  • 有一个标准的简单指令系统,如加减乘除赋值等
  • 每件简单的工作都恰好花费一个一个时间单位
  • 不存在矩阵求逆、排序等操作
  • 无限内存

你可能感兴趣的:(数据结构与算法)