Skip to content

第1章 绪论

本章介绍数据结构的基本概念、算法复杂度分析方法。掌握时间复杂度的计算方法是考研的必备基础。


1. 数据结构基本概念

数据结构三要素

数据结构是一个二元组 D = (D, S),其中 D 是数据元素的有限集合,S 是 D 上关系的有限集合。数据结构包含三个要素:

要素说明例子
逻辑结构元素之间的逻辑关系,独立于计算机存储线性结构、树形结构、图形结构
存储结构数据在计算机中的存储方式顺序存储、链式存储
数据运算对数据元素的操作插入、删除、查找、遍历

逻辑结构分类

线性结构:元素之间一对一关系

  • 线性表、栈、队列、串

非线性结构

  • 树形结构:元素之间一对多关系(树、二叉树)
  • 图形结构:元素之间多对多关系(有向图、无向图)
  • 集合结构:元素之间除"同属一个集合"外无其他关系

存储结构分类

顺序存储:用连续地址存储,逻辑相邻=物理相邻

  • 优点:随机存取O(1)、空间利用率高
  • 缺点:插入删除需移动元素、需预先分配连续空间

链式存储:用指针表示逻辑关系

  • 优点:插入删除O(1)、动态分配空间
  • 缺点:不能随机存取、指针占用额外空间

2. 时间复杂度

大O记号定义

若存在正常数 c 和 n₀,使得当 n ≥ n₀ 时,有 0 ≤ T(n) ≤ c·f(n),则称 T(n) = O(f(n))

大O记号表示算法时间复杂度的上界

常见复杂度排序

O(1) < O(log₂n) < O(n) < O(nlog₂n) < O(n²) < O(n³) < O(2ⁿ) < O(n!) < O(nⁿ)

时间复杂度计算方法

累加法(循环嵌套)

python
def example1(n):
    count = 0
    for i in range(n):       # 执行 n 次
        for j in range(n):   # 执行 n 次
            count += 1       # O(1)
    # 总次数 = n × n = n²
    # 时间复杂度 = O(n²)
    return count

计算思路:循环嵌套的次数相乘

乘法法则(循环内外)

python
def example2(n):
    for i in range(n):       # On)
        pass
    for j in range(n*n):     # O(n²)
        pass
    # 总复杂度 = O(n) + O(n²) = O(n²)

计算思路:并列取最大值

递归法(递推方程)

示例1:阶乘递归

python
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

递推式:T(n) = T(n-1) + O(1) 展开:T(n) = T(n-2) + O(1) + O(1) = ... = O(n)

示例2:斐波那契

python
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

递推式:T(n) = T(n-1) + T(n-2) + O(1) = O(2ⁿ)

示例3:二分查找

递推式:T(n) = T(n/2) + O(1) 展开:T(n) = T(n/4) + O(1) + O(1) = O(log₂n)

手写计算示例

计算以下代码的时间复杂度:

python
def mystery(n):
    for i in range(1, n+1):      # i = 1, 2, 3, ..., n
        for j in range(i):        # j = 0, 1, ..., i-1
            print(i, j)

分析过程

i=1 时:j 循环 1 次
i=2 时:j 循环 2 次
...
i=n 时:j 循环 n 次

总次数 = 1 + 2 + 3 + ... + n = n(n+1)/2 = O(n²)

3. 空间复杂度

定义

算法所需额外存储空间的规模,记为 S(n) = O(g(n))

原地算法

如果算法所需辅助空间为常数,即 O(1),则称该算法为原地算法

示例:冒泡排序

python
def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    # 只用了常数个临时变量 (i, j, n)
    # 空间复杂度 = O(1),原地算法

对比:归并排序

python
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])   # 需要额外空间
    right = merge_sort(arr[mid:])  # 需要额外空间
    return merge(left, right)
    # 空间复杂度 = O(n),非原地算法

4. 考研重点 & 易错点

高频考点

考点要点
时间复杂度计算递推式求解、循环嵌套分析
大O记号只保留最高次项,系数为1
常见算法复杂度二分查找O(logn)、快速排序O(nlogn)等
数据结构三要素逻辑结构、存储结构、数据运算

易错点

易错点正确理解
混淆平均、最坏、最好复杂度考研默认指最坏时间复杂度
递归算法复杂度计算必须写出递推式再求解
空间复杂度忽略输入空间只计算算法使用的额外空间
log₂n 底数省略在大O记号中底数不重要

常用计算技巧

等比数列求和1 + 2 + 4 + ... + 2^k = 2^(k+1) - 1

调和级数1 + 1/2 + 1/3 + ... + 1/n ≈ ln n


5. 算法效率对比表

操作/算法时间复杂度适用场景
顺序查找O(n)无序、小规模
二分查找O(logn)有序顺序表
冒泡/插入排序O(n²)小规模、基本有序
快速/归并/堆排序O(nlogn)大规模
斐波那契递归O(2ⁿ)❌ 应改用动态规划
矩阵乘法O(n³)可用优化算法

📝 代码示例:复杂度分析工具

python
def analyze_complexity():
    """
    示例代码,展示不同复杂度
    """
    n = 100

    # O(1) 常数时间
    x = n + 1

    # O(logn) 对数时间
    i = 1
    while i < n:
        i *= 2

    # O(n) 线性时间
    for i in range(n):
        pass

    # O(nlogn) 线性对数时间
    for i in range(n):
        j = 1
        while j < n:
            j *= 2

    # O(n²) 平方时间
    for i in range(n):
        for j in range(n):
            pass


if __name__ == "__main__":
    analyze_complexity()
    print("复杂度分析示例执行完成")
最近更新

基于 MIT 许可发布