第2章 算法分析基础

2-1 算法的时间复杂度分析

2.1.1 输入规模与基本语句

  • 输入规模:算法处理数据的规模,通常用 n 表示。

  • 基本语句:执行次数与输入规模直接相关的关键操作。

  • 例2.1 顺序查找

    复制代码
    int SeqSearch(int A[], int n, int k) {  
        for (int i = 0; i < n; i++)  
            if (A[i] == k) break;  
        if (i == n) return 0;  
        else return (i + 1);  
    }
    • 输入规模 n;基本语句是"比较 A[i] == k"

2.1.2 渐近分析

  • 大 O、大 Ω、大 Θ

    • T(n)=O(f(n)):∃ c, n₀, ∀ n ≥ n₀, T(n) ≤ c·f(n)

    • T(n)=Ω(f(n)):∃ c, n₀, ∀ n ≥ n₀, T(n) ≥ c·f(n)

    • T(n)=Θ(f(n)):同时满足 O(f(n)) 和 Ω(f(n))

  • 例:若 T(n) ≤ 100n + n 则 T(n)=O(n)

    • 取 n₀=5, c=101, 则 ∀ n ≥ 5, T(n) ≤ 101n → O(n)
  • 常见增长阶

    1 < log n < n < n log n < n² < n³ < ... < 2ⁿ < n!

  • 例2.4 合并算法

    复制代码
    void Union(int A[], int n, int B[], int m, int C[]) {
        int i=0, j=0, k=0;
        while (i<n && j<m) {
            if (A[i] <= B[j]) C[k++] = A[i++];
            else C[k++] = B[j++];
        }
        while (i<n) C[k++] = A[i++];
        while (j<m) C[k++] = B[j++];
    }
    • 时间复杂度 O(n + m)

2.1.3 最好、最坏和平均情况

  • 当算法执行代价依赖于不同输入时,需要分别分析:

    • 最好情况:最少操作次数;

    • 最坏情况:最多操作次数;

    • 平均情况:所有输入实例上的平均操作次数。

  • 顺序查找例

    • 最好:第1个元素即中,比较1次;

    • 最坏:未找到或在末尾,比较n次;

    • 平均:约(n + 1)/2次


2-2 算法的空间复杂度分析

  • 空间复杂度 = 输入/输出数据占用 + 算法本身占用 + 辅助空间

    1. 输入/输出数据:题目本身的数据结构;

    2. 算法本身:局部变量、常量,通常为 O(1);

    3. 辅助空间:临时数组、递归栈等。

  • 示例

    • CommonFactor 求最大公约数:仅用常数级局部变量,O(1);

    • BubbleSort:只用固定数量的索引和临时变量,O(1);

    • Merge:需要长度为 n 的临时数组,O(n)。


2-3 算法的实验分析

  • 实验分析:将算法实现为程序,上机运行,实际测算时空开销

  • 常用度量方法

    1. 计数法:插入计数器,记录关键语句执行次数;

    2. 计时法:记录程序段开始和结束时间,计算时间差。

  • 例 BubbleSort 实验

    复制代码
    void BubbleSort(int r[], int n) {
        int j, temp, count1=0, count2=0, bound, exchange=n-1;
        while (exchange != 0) {
            bound = exchange; exchange = 0;
            for (j = 0; j < bound; j++)
                if (++count1 && r[j] > r[j+1]) {
                    temp = r[j]; r[j] = r[j+1]; r[j+1] = temp;
                    count2 += 3; exchange = j;
                }
        }
        cout<<"比较次数="<<count1<<",移动次数="<<count2<<endl;
    }
    • 目的:统计比较次数和移动次数
  • Collatz 过程实验

    • 规则:n 为奇数 → 3n+1,否则 → n/2,直到 n=1;

    • 例 n=9:{9,28,14,...,1};

    • 例 n=27:77步到9232,再32步到1。


2-4 拓展与演练:最优算法与下界

  • 下界 Ω 表示法

    若 ∃ c, n₀, ∀ n ≥ n₀, T(n) ≥ c·g(n),则 T(n)=Ω(g(n)),g(n) 是问题的时间下界

  • 最优算法

    如果问题已知下界 g(n),且算法满足 T(n)=Θ(g(n)),则该算法为最优。

  • 例2.10 最小值算法

    复制代码
    int ArrayMin(int a[], int n) {
        int min = a[0];
        for (int i = 1; i < n; i++)
            if (a[i] < min) min = a[i];
        return min;
    }
    • 比较次数下界 Ω(n),算法时间 O(n),故为最优。
相关推荐
Lear3 分钟前
【数组】代码随想录 44.开发商购买土地
算法
CoovallyAIHub9 分钟前
OmniNWM:突破自动驾驶世界模型三大瓶颈,全景多模态仿真新标杆(附代码地址)
深度学习·算法·计算机视觉
努力努力再努力wz13 分钟前
【Linux进阶系列】:信号(下)
java·linux·运维·服务器·开发语言·数据结构·c++
TU^33 分钟前
C语言习题~day27
c语言·数据结构·算法
2401_8414956441 分钟前
【自然语言处理】Transformer模型
人工智能·python·深度学习·算法·语言模型·自然语言处理·transformer
m0_7482336441 分钟前
C++与Python:内存管理与指针的对比
java·c++·python
孤廖42 分钟前
面试官问 Linux 编译调试?gcc 编译流程 + gdb 断点调试 + git 版本控制,连 Makefile 都标好了
linux·服务器·c++·人工智能·git·算法·github
软件2051 小时前
【JDK、JRE、JVM】
java·开发语言·jvm
m0_748255411 小时前
TailwindCSS vs UnoCSS 性能深度对决:究竟快多少?
java
薛家明1 小时前
easy-query暴打efcore(包括其他所有orm),隐式Group看我如何在子查询做到极致的性能天花板
java·orm·efcore·easy-query·entityframeworkcore·dotnetcore