衡量程序运行效率之时间复杂度和空间复杂度

复杂度是衡量代码运行效率的重要的度量因素。

复杂度与计算机实际任务处理的效率

计算机通过程序去执行计算任务,也就是对输入数据的加工处理并得到结果的过程。对于相同的任务,不同的计算方法导致计算过程的复杂程度不同,比如:

假设一个任务,系统平均每秒新增10M数据,如果你的代码不能在1分钟内处理10M数据,系统就会发生时间爆炸和空间爆炸。因此需要尽可能地降低计算复杂度。

衡量复杂度的维度:时间复杂度和空间复杂度

你的代码在执行的时候消耗的是计算时间和计算空间,那么就需要去衡量时间复杂度和空间复杂度。

有了时间复杂度和空间复杂度,我们就要关注其消耗的资源量有多少。为了更客观的比较,我们通常会更关注时间或空间消耗量与输入数据之间的关系。

计算复杂度

复杂度是一个关于输入数据量 n 的函数。假设你的代码复杂度是 f(n),那么就用个大写字母 O 和括号,把 f(n) 括起来就可以了,即 O(f(n))。例如,O(n) 表示的是,复杂度与计算实例的个数 n 线性相关;O(logn) 表示的是,复杂度与计算实例的个数 n 对数相关。

通常,复杂度的计算方法遵循以下几个原则:

首先,复杂度与具体的常系数无关,例如 O(n) 和 O(2n) 表示的是同样的复杂度。我们详细分析下,O(2n) 等于 O(n+n),也等于 O(n) + O(n)。也就是说,一段 O(n) 复杂度的代码只是先后执行两遍 O(n),其复杂度是一致的。
其次,多项式级的复杂度相加的时候,选择高者作为结果,例如 O(n²)+O(n) 和 O(n²) 表示的是同样的复杂度。具体分析一下就是,O(n²)+O(n) = O(n²+n)。随着 n 越来越大,二阶多项式的变化率是要比一阶多项式更大的。因此,只需要通过更大变化率的二阶多项式来表征复杂度就可以了。
值得一提的是,O(1) 也是表示一个特殊复杂度,含义为某个任务通过有限可数的资源即可完成。此处有限可数的具体意义是,与输入数据量 n 无关。

时间复杂度与代码结构的关系

  • 一个顺序结构的代码,时间复杂度是 O(1)。
  • 二分查找,或者更通用地说是采用分而治之的二分策略,时间复杂度都是 O(logn)。这个我们会在后续课程讲到。
  • 一个简单的 for 循环,时间复杂度是 O(n)。
  • 两个顺序执行的 for 循环,时间复杂度是 O(n)+O(n)=O(2n),其实也是 O(n)。
  • 两个嵌套的 for 循环,时间复杂度是 O(n²)。

总的来说:

复杂度与具体的常系数无关,O(n) 和 O(2n) 表示的是同样的复杂度。

复杂度相加的时候,选择高者作为结果,也就是说 O(n²)+O(n) 和 O(n²) 表示的是同样的复杂度。

O(1) 也是表示一个特殊复杂度,即任务与算例个数 n 无关。

猜你喜欢

转载自www.cnblogs.com/aaronthon/p/12961779.html