总体分析
在程序设计中,为了完成某些功能,工程师们会设计一些算法,来完成这些功能。然而完成这些功能的时候不可避免的会遇到一些效率问题,而时间复杂度和空间复杂度具有算法运行时衡量算法效率的作用
。
一般情况下,算法的时间复杂度与空间复杂度是成反比的
,当一个算法时间复杂度降低,这个算法的空间复杂度会相应升高。二者经常不可得兼
。
时间复杂度
找到某条语句与问题规模N之间的表达式,就是算出了该算法的时间复杂度
例如之下代码
int main()
{
int i = 0;
int sum = 0;
for (i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
//O(1);
}
return 0;
}
这个代码的时间复杂度就是 O(N*N) 即 O(N²)
一般情况下我们使用最坏情况表示时间复杂度,比如:
int search(int target)
{
int a[N] = { 1, 2, 3, 4, 5, 6, 7, ..., N };
for (int i = 0; i < N; i++)
{
if (target == a[i])
{
return 1;
}
}
return 0;
}
这是一段遍历查找代码
此代码最好情况便是第一次直接匹配成功,那么这个代码时间复杂度是不是 O(1) 呢?或者是 O(N/2) ?还是 O(N) ?答案是·O(N)
我们一般认为时间复杂度是算法最坏情况下的时间复杂度
。
常见时间复杂度对应表
时间复杂度 | 概述 | 算法 |
---|---|---|
O(n^2) | 数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度 | 冒泡排序 |
O(logn) | 当数据增大n倍时,耗时增大log n倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度) | 二分查找 |
O(nlogn) | 当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。 | 归并排序 |
空间复杂度
空间复杂度表示的是在算法运行过程中额外申请的空间的个数就,不将算法本身的数据存储空间计算在内
如交换数值算法:
算法一
int main()
{
int a = 10;
int b = 20;
int tmp = 0;
tmp = a;
a = b;
b = tmp;
return 0;
}
算法二
int main()
{
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
return 0;
}
以上两个算法都是交换两个变量的数值,但算法一使用了一个额外变量,所以算法一的时间复杂度就是 O(1) 。 算法二无额外变量
,所以算法二的时间复杂度就是 O(0)