|
|
|
|
# 算法效率评估
|
|
|
|
|
|
|
|
|
|
在算法设计中,我们先后追求以下两个层面的目标:
|
|
|
|
|
|
|
|
|
|
1. **找到问题解法**:算法需要在规定的输入范围内,可靠地求得问题的正确解。
|
|
|
|
|
2. **寻求最优解法**:同一个问题可能存在多种解法,我们希望找到尽可能高效的算法。
|
|
|
|
|
|
|
|
|
|
因此在能够解决问题的前提下,算法效率成为主要的评价维度,包括:
|
|
|
|
|
|
|
|
|
|
- **时间效率**:算法运行速度的快慢。
|
|
|
|
|
- **空间效率**:算法占用内存空间的大小。
|
|
|
|
|
|
|
|
|
|
简而言之,**我们的目标是设计“既快又省”的数据结构与算法**。而有效地评估算法效率至关重要,因为只有这样我们才能将各种算法进行对比,从而指导算法设计与优化过程。
|
|
|
|
|
|
|
|
|
|
效率评估方法主要分为两种:实际测试和理论估算。
|
|
|
|
|
|
|
|
|
|
## 实际测试
|
|
|
|
|
|
|
|
|
|
假设我们现在有算法 `A` 和算法 `B` ,它们都能解决同一问题,现在需要对比这两个算法的效率。最直接的方法是找一台计算机,运行这两个算法,并监控记录它们的运行时间和内存占用情况。这种评估方式能够反映真实情况,但也存在较大局限性。
|
|
|
|
|
|
|
|
|
|
**难以排除测试环境的干扰因素**。硬件配置会影响算法的性能表现。比如在某台计算机中,算法 `A` 的运行时间比算法 `B` 短;但在另一台配置不同的计算机中,我们可能得到相反的测试结果。这意味着我们需要在各种机器上进行测试,统计平均效率,而这是不现实的。
|
|
|
|
|
|
|
|
|
|
**展开完整测试非常耗费资源**。随着输入数据量的变化,算法会表现出不同的效率。例如,在输入数据量较小时,算法 `A` 的运行时间比算法 `B` 更少;而输入数据量较大时,测试结果可能恰恰相反。因此,为了得到有说服力的结论,我们需要测试各种规模的输入数据,而这样需要耗费大量的计算资源。
|
|
|
|
|
|
|
|
|
|
## 理论估算
|
|
|
|
|
|
|
|
|
|
由于实际测试具有较大的局限性,我们可以考虑仅通过一些计算来评估算法的效率。这种估算方法被称为「渐近复杂度分析 Asymptotic Complexity Analysis」,简称为「复杂度分析」。
|
|
|
|
|
|
|
|
|
|
**复杂度分析评估的是算法运行效率随着输入数据量增多时的增长趋势**。这个定义有些拗口,我们可以将其分为三个重点来理解:
|
|
|
|
|
|
|
|
|
|
1. “算法运行效率”可分为运行时间和占用空间两部分,与之对应地,复杂度可分为「时间复杂度 Time Complexity」和「空间复杂度 Space Complexity」。
|
|
|
|
|
2. “随着输入数据量增多时”意味着复杂度反映了算法运行效率与输入数据量之间的关系。
|
|
|
|
|
3. “增长趋势”表示复杂度分析关注的是算法时间与空间的增长趋势,而非具体的运行时间或占用空间。
|
|
|
|
|
|
|
|
|
|
**复杂度分析克服了实际测试方法的弊端**。首先,它独立于测试环境,分析结果适用于所有运行平台。其次,它可以体现不同数据量下的算法效率,尤其是在大数据量下的算法性能。
|
|
|
|
|
|
|
|
|
|
如果你对复杂度分析的概念仍感到困惑,无需担心,我们会在后续章节详细介绍。
|
|
|
|
|
|
|
|
|
|
## 复杂度的重要性
|
|
|
|
|
|
|
|
|
|
复杂度分析为我们提供了一把评估算法效率的“标尺”,帮助我们衡量了执行某个算法所需的时间和空间资源,并使我们能够对比不同算法之间的效率。
|
|
|
|
|
|
|
|
|
|
复杂度是个数学概念,对于初学者可能比较抽象,学习难度相对较高。从这个角度看,复杂度分析可能不太适合作为第一章的内容。
|
|
|
|
|
|
|
|
|
|
然而,当我们讨论某个数据结构或算法的特点时,难以避免要分析其运行速度和空间使用情况。因此,在深入学习数据结构与算法之前,**建议你先对复杂度建立初步的了解,能够完成简单算法的复杂度分析**。
|