时间复杂度(Time Complexity):用于衡量算法在执行过程中所需的基本操作次数随输入规模 (n) 增长的趋势。通常关注其渐近行为,忽略常数项和低阶项的影响。
空间复杂度(Space Complexity):指算法在运行过程中所占用的额外内存空间(不包含输入数据本身)随着输入规模 (n) 的增长情况。
渐近记号(Asymptotic Notation):
最好、最坏与平均情况分析:
push_back
push
以下列出主要数据结构及算法在典型操作下的平均与最坏时间复杂度,以及额外空间开销(注:(n) 表示节点数量,(m) 表示边数;α(n) 为反阿克曼函数,增长极缓,实际中可视为常数)。
| 数据结构/算法 | 查找 | 插入 | 删除 | 构造/遍历 | 空间 |
|---|---|---|---|---|---|
| 数组(支持随机访问) | O(1) | O(n)(中间插入) | O(n) | O(n) | O(1)(额外) |
| 动态数组 / vector(摊销分析) | O(1) 访问 | 均摊 O(1)(末尾插入),最坏 O(n)(扩容) | O(1) 尾部删除 | O(n) | O(n) |
| 单链表 | O(n) | O(1)(头部插入) | O(1)(已知前驱节点) | O(n) | O(1) |
| 双向链表 | O(n) | O(1)(已知位置) | O(1) | O(n) | O(1) |
| 哈希表(均匀散列,链地址法或开放寻址) | 平均 O(1),最坏 O(n) | 平均 O(1),最坏 O(n) | 平均 O(1) | O(n) | O(n) |
| 平衡二叉搜索树(AVL / 红黑树) | O(log n) | O(log n) | O(log n) | O(n) | O(n) |
| 堆(二叉堆) | — | O(log n) 插入 | O(log n) 弹出最值 | O(n) | O(n) |
| 并查集(路径压缩 + 按秩合并) | α(n) | α(n) | — | O(n) | O(n) |
| BFS / DFS(邻接表存储) | — | — | — | O(n + m) 时间,O(n) 额外空间 | O(n + m) 存图 |
| Dijkstra(使用二叉堆) | — | — | — | O(m log n) | O(n + m) |
| Dijkstra(使用斐波那契堆优化) | — | — | — | O(n log n + m) | O(n + m) |
| Kruskal 算法 | — | — | — | O(m log m)(排序)+ α(n) | O(n + m) |
| 快速排序 | 平均 O(n log n),最坏 O(n)(退化情形) | — | — | 平均 O(log n) 递归栈 | O(1) 或 O(log n) 额外空间 |
| 归并排序 | O(n log n) | O(n log n) | — | O(n) 额外空间 | O(n) 额外空间 |
push_back
对于形如 (T(n) = aT(n/b) + f(n)) 的递推关系,常用以下策略进行分析:
这些方法帮助我们准确评估递归算法的时间复杂度,尤其在分治、动态规划和树形结构遍历中广泛应用。
find主定理(Master Theorem)是分析分治算法时间复杂度的重要工具。其适用形式为递推关系式:
T(n) = aT(n/b) + f(n),其中 a ≥ 1,b > 1。
通过比较函数 f(n) 与 nlogba 的增长速率,主定理可将结果分为以下三种情况:
若 f(n) = O(nlogba - ε),其中 ε > 0,则 T(n) = Θ(nlogba)。
若 f(n) = Θ(nlogba logkn),k ≥ 0,则 T(n) = Θ(nlogba logk+1n)。
若 f(n) = Ω(nlogba + ε),且满足正则条件 af(n/b) ≤ cf(n)(对某个 c < 1 和足够大的 n 成立),则 T(n) = Θ(f(n))。
push_back
常见应用实例包括:
push
除了主定理外,递归树法、主定理的变体以及替代法(即提出猜想并通过数学归纳法证明)也是求解递推式的常用手段。
均摊复杂度关注的是一系列操作的整体性能表现,而非单个操作的最坏情况。对于一个长度为 m 的操作序列,若总时间成本为 O(m·a(n)),则称每次操作的均摊代价为 O(a(n))。这意味着尽管某些操作可能开销较大,但整体上平均每步的代价仍然可控。
常用的均摊分析方法有以下三种:
聚合方法(Aggregate Method):
计算 m 次操作的总成本 T(m),然后取平均值 T(m)/m 来得出均摊代价。
记账方法(Accounting Method):
为每个操作设定一个“摊还费用”,高于实际成本的部分视为存入“信用账户”,用于抵消后续高成本操作的支出。必须确保任意时刻的操作都能被账户中的余额覆盖。
势能方法(Potential Method):
引入一个势能函数 Φ,它将数据结构的状态映射为一个非负实数。第 i 次操作的摊还成本定义为:ci + Φ(Si) - Φ(Si-1),其中 ci 是实际成本,Si 表示第 i 步后的状态。整个操作序列的总摊还成本等于实际总成本加上末态与初态势能之差 Φ(Sm) - Φ(S0)。合理构造 Φ 可有效证明复杂度上界。
在实现如动态数组(例如 ArrayList 或 vector)时,当存储空间不足时通常采用“容量翻倍”策略:新建一个大小为原容量两倍的新数组,并将原有元素全部复制过去。
操作代价分析:
使用不同方法进行均摊分析:
聚合方法:
考虑从空数组开始执行 n 次插入操作。总共发生的复制次数可以累加估算:最后一次扩容最多复制 n 个元素,前一次最多复制 n/2,再前一次 n/4,依此类推。总复制量不超过 n + n/2 + n/4 + ... < 2n,因此总成本为 O(n),均摊到每次操作为 O(1)。
记账方法:
为每次插入操作收取 3 单位摊还费用:1 单位用于当前插入操作本身,其余 2 单位作为预存“信用”。每当发生扩容时,这些预先积累的信用可用于支付元素迁移的成本,从而保证整体平衡。
势能方法:
定义势能函数 Φ = 2 × size - capacity,其中 size 是当前元素个数,capacity 是当前容量。该函数反映了系统中“未使用的潜力”。利用此函数可严格推导出每次操作的摊还成本为常数级。
综上所述,动态数组的插入操作具有 O(1) 的均摊时间复杂度。
结论:
均摊复杂度为 O(1),但单次操作最坏情况为 O(n)。
push_back
主要操作包括:
find 与 union。
对于任意 m 个操作,总时间复杂度为 O(mα(n)),其中 α(n) 是反阿克曼函数。该函数增长极其缓慢,在实际应用范围内通常不超过 4。
其证明依赖于复杂的摊还分析方法(如 Tarjan 提出的函数序列法),此处不展开细节。结论是:每次操作的均摊代价接近常数级别。
在二叉堆中:
insert 和 extract-min 操作的时间复杂度如下:
insert:最坏情况下为 O(log n)(元素上浮过程),均摊也为 O(log n),无摊还优势。Fibonacci 堆则提供更优的均摊性能:
insert:均摊 O(1)decrease-key:均摊 O(1)extract-min:均摊 O(log n)尽管性能优越,其实现机制较为复杂。
伸展树通过自调整结构实现高效访问。查找、插入、删除等操作的均摊时间复杂度均为 O(log n)。
该结果基于势能函数分析,该函数反映树的整体“不平衡程度”或未来的潜在操作成本。对任意访问序列,单次操作的均摊开销可被控制在对数级别。
注意:应区分输入本身占用的空间与算法所需的额外辅助空间(auxiliary space)。通常,“额外空间”不包含输入所占内存。
在算法分析中,除了传统的时间复杂度之外,还需考虑多种扩展模型来更精确地刻画性能表现。以下是几个关键的分析维度:
PRAM 模型:该模型关注并行计算中的时间、工作量(work)与深度(span)之间的关系。其中,“工作量”指所有处理器执行的操作总数,“深度”表示最长的依赖路径,即并行执行所需的时间下界。
外存模型(I/O 复杂度):适用于数据规模超出内存容量的场景,重点在于块访问次数(记为 B),以及可用内存大小(记为 M)。目标是最小化磁盘 I/O 操作,而非单纯的 CPU 运算次数。
分布式系统的通信成本:在网络环境下,时间开销不仅来自计算,还显著受网络往返延迟和消息数量的影响。减少通信轮次和传输量是优化的关键方向。
参数化复杂度与近似算法:面对 NP-hard 问题时,常采用参数化方法(如 FPT 算法)或设计近似算法,在可接受时间内获得接近最优解的结果。
push
考虑一个初始容量为 1 的空动态数组,进行 n 次插入操作:
扩容过程发生的容量点为:1, 2, 4, 8, ..., 直至不超过 n。
总的复制次数为等比数列求和:
1 + 2 + 4 + ... ≤ n,其和严格小于 2n。
因此,包括插入和复制在内的总写操作次数不超过 3n,均摊到每次插入的成本不超过 3,故均摊时间复杂度为 O(1)。
记账法解释:
每次插入收取 3 单位费用:
当发生扩容并需复制 k 个元素时,这 k 个元素各自之前已积累 2 单位,足以支付复制成本,系统始终不会透支。
势能法建模:
定义势函数 Φ = 2 × size - capacity(保证非负)。通过该函数可证明每一步的实际成本加上势能变化量恒定,从而得出摊还成本为 O(1)。
扫码加好友,拉您进群



收藏
