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

算法时间复杂度分析

1. 基本概念

  • 大 O 符号 O(f(n))
    表示算法的最坏情况复杂度,即算法在最不利情况下所需的基本操作数不会超过 O(f(n))的级别。例如,O(n^2)表示当输入规模 n 增大时,算法运行时间上界是某个常数乘以 n^2

  • Ω 符号 Ω(f(n))
    表示算法的下界,即在任何情况下,算法至少需要做 Ω(f(n)) 数量级的基本操作。

  • Θ 符号 Θ(f(n))
    当一个算法的上界和下界都为 f(n) 的量级时,我们就说该算法的时间复杂度是 Θ(f(n))。

  • 平均时间复杂度
    对所有可能输入的运行时间取平均得到的复杂度,反映了算法在一般情况下的表现。


2. 递归关系与主定理

在分析递归算法时,常用以下递归公式和工具:

  • 递归公式的一般形式

    T(n) = aT\left(\frac{n}{b}\right) + f(n)

    其中 a≥1 、b> 且 f(n) 是非递归部分的工作量。

  • 主定理(Master Theorem)
    用于求解上述递归公式,其结果通常分为三种情况:

    • 情况 1: 如果f(n) = O\left(n^{\log_b a-\epsilon}\right)对于某个 ϵ>0,那么

      T(n)=\Theta\left(n^{\log_b a}\right).
    • 情况 2: 如果 f(n)=\Theta\left(n^{\log_b a}\right),则

      T(n)=\Theta\left(n^{\log_b a}\log n\right).
    • 情况 3: 如果f(n)=\Omega\left(n^{\log_b a+\epsilon}\right) 对于某个 ϵ>0 ,并且满足正则性条件,则

      T(n)=\Theta\left(f(n)\right).

举例说明:
对于归并排序,递归公式为

T(n)=2T\left(\frac{n}{2}\right)+O(n)

这里 a=2 、b=2 ,且 f(n)=O(n) 与 n^{\log_2 2}=n 同级,故满足情况2,有

T(n)=\Theta(n\log n).


3. 递归树法与迭代法

  • 递归树法
    将递归公式分解成一棵树,求解各层的工作量和总的层数,最终将各层的工作量累加求和。例如,对于递归关系

    T(n)=T(n-1)+O(1),

    递归树有 n 层,每层成本为 O(1) ,因此总时间复杂度为 O(n)。

  • 迭代法
    将递归公式展开,寻找通项后求和。例如,对于

    T(n)=T(n-1)+O(n),

    展开后可得到

    T(n)=T(1)+O\left(\sum_{i=2}^{n} i\right)=O(n^2).

4. 求和公式与级数

很多算法分析中需要利用常见的求和公式,常见的有:

  • 算术级数:

    \sum_{i=1}^n i = \frac{n(n+1)}{2} = \Theta(n^2).
  • 几何级数:

    \sum_{i=0}^{k} a^i = \frac{a^{k+1}-1}{a-1}, \quad a\neq1,

    k=\log_a n 时,总量大约为 Θ(n) 。

  • 调和级数:

\sum_{i=1}^n \frac{1}{i} = \Theta(\log n).


5. 分析方法

  • 计数基本操作
    通常选择算法中最耗时的操作(例如循环体内的语句、比较或交换等)进行计数,推导出操作数的数学表达式,再用大 O 表示。

  • 分步分析
    对于嵌套循环、递归算法或分治算法,分别分析各部分的时间复杂度,最后根据乘法或加法规则得出整体时间复杂度。

  • 递归关系与主定理
    对于递归算法,可以建立递归关系(例如 T(n)=2T(n/2)+O(n)),使用递归树或主定理求解出 T(n)的量级。


6. 典型算法时间复杂度举例

  1. 线性搜索 (Linear Search)

    • 过程:在一个长度为 n 的数组中逐个比较元素,查找目标值。

    • 时间复杂度:最坏情况下需要比较所有 n 个元素,故为 O(n)。

  2. 二分搜索 (Binary Search)

    • 过程:在一个有序数组中,通过每次将搜索区间减半来查找目标值。

    • 时间复杂度:每次操作将问题规模缩小一半,故为 O(log⁡n)。

  3. 冒泡排序 (Bubble Sort)

    • 过程:重复遍历数组,比较相邻元素并交换使得最大(或最小)元素逐步“冒泡”到末端。

    • 时间复杂度:最坏情况需要进行大约 \frac{n(n-1)}{2} 次比较,故为 O(n^2)

  4. 归并排序 (Merge Sort)

    • 过程:采用分治策略将数组分为若干子数组进行排序,再归并。

    • 时间复杂度:分解为两个规模为 n/2 的子问题,再加上归并操作的 O(n) 时间,递归关系为 T(n)=2T(n/2)+O(n) ,解得为 O(nlog⁡n) 。

  5. 快速排序 (Quick Sort)

    • 过程:选取基准元素,将数组划分为两部分,再递归排序。

    • 时间复杂度:平均情况下为 O(nlog⁡n) ;但在最坏情况下(例如每次选取的基准都是极端值),时间复杂度为O(n^2)

  6. Dijkstra 算法(使用邻接矩阵)

    • 过程:寻找单源最短路径,采用贪心策略不断更新路径。

    • 时间复杂度:对每个节点都需扫描所有节点,故为 O(n^2);如果采用堆优化,则复杂度可降低为 O((n+e) \log n)(其中 e 边数)。


7. 分析实例:归并排序

我们来具体看归并排序的时间复杂度分析:

  1. 分解阶段
    将问题分解为两个子问题,每个子问题的规模为 n/2 ,这一步的时间复杂度为 2T(n/2) 。

  2. 合并阶段
    将两个已排序的子数组归并成一个有序数组需要 O(n) 时间。

  3. 递归关系
    总时间复杂度满足递归关系

    T(n)=2T(n/2)+O(n).
  4. 求解递归关系
    根据主定理,此递归关系的解为

    T(n)=O(nlog⁡n). 

8. 总结

  • 分析方法
    对于任何算法,分析其循环、递归及分治过程,找出最耗时的基本操作,建立数学模型,再用大 O、Ω、Θ 符号描述。

  • 典型例子

    • 线性搜索:O(n) 

    • 二分搜索:O(log⁡n) 

    • 冒泡排序:O(n^2)

    • 归并排序:O(nlog⁡n) 

    • 快速排序:平均 O(nlog⁡n)),最坏 O(n^2)

    • Dijkstra 算法(无堆):O(n^2),(堆优化):O((n+e) \log n)

相关文章:

  • 分布式特性对比
  • AI Agent:构建以数据为中心的智能体
  • Unity高清渲染管线
  • MOSN(Modular Open Smart Network)-05-MOSN 平滑升级原理解析
  • Go 语言 sync 包使用教程
  • [C++面试] RAII资源获取即初始化(重点)
  • 探究 Arm Compiler for Embedded 6 的 Clang 版本
  • 3.26[a]paracompute homework
  • IGS 转 STL 全攻略:迪威模型在线转码助力 3D 建模
  • ubuntu22.04下gazebo harmonic使用学习
  • Docker基本命令VS Code远程连接
  • P4147 玉蟾宫
  • Linux系统加固笔记
  • LLM - 白话Reranker模型
  • Cortex-M7进入异常中断分析
  • 写一个输入框校验类,链式实现表单校验
  • sql2022 复制 事务级别发布后无法删除
  • 在IDEA中使用TortoiseSVN
  • 自然语言处理(NLP)技术的应用面有哪些
  • 往期项目shader着色器实践效果应用合集
  • 总粉丝破亿!当网络大V遇见硬核科技,互联网时代如何书写上海故事?
  • 国博馆刊|北朝至唐初夏州酋豪李氏家族的发展与身份记忆
  • 人民日报评“组团退演出服”:市场经济诚信原则需全社会维护
  • 洛杉矶奥组委确认2028年奥运会和残奥会开闭幕式场地
  • 戴维·珀杜宣誓就任美国驻华大使
  • 习近平在俄罗斯媒体发表署名文章