衡量算法效率的两个指标
一位瑞士的计算机学者曾提出 这样的观点“程序设计 = 算法 + 数据结构” ,可见算法在计算机编程中具有重要地位。下面给出衡量算法性能的两个指标:
- 时间复杂度 T(n)
- 空间复杂度 S(n)
时间复杂度
算法的时间复杂度是指算法执行时间随问题规模n的增大而增长的趋势,它是一个定性指标,是一种趋势性的描述,而不是具体的执行时间。
衡量时间复杂度是指==从算法中选取一种对于所研究的问题来说是基本操作的原操作,以该基本操作在算法中重复执行的次数作为算法时间复杂度的依据。
例如:
int fun(int n)
{
int s = 0;
//最外层执行测试为n
for (int i = 0; i < n; i++)
{
for (int j = 1; j < i;j++)
{
//s += i*j是原操作,其重复次数是作为时间复杂度的依据
s += i * j;
}
}
return s;
}
该算法中 s += i * j
总共执行了
(
n
−
1
)
(
n
−
1
)
2
\frac{(n-1)(n-1)}{2}
2(n−1)(n−1)次,取最高次幂,其T(n)= O(
n
2
n^2
n2)。
常见的时间复杂度量级有:
- 常数阶O(1)
- 对数阶O(logN)
- 线性阶O(n)
- 线性对数阶O(nlogN)
- 平方阶O(n²)
- 立方阶O(n³)
- 指数阶(2^n)
它们的时间复杂度越来越大,算法执行效率越来越低,下面举例常见的示例。
1、O(1)空间复杂度
无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1),即是个常量时间,和问题规模无关。如:
int i = 1;
int j = 2;
int m = i + j;
2、对数阶O(logN)
int i = 1;
while(i<n)
{
i = i * 2;
}
3、线性对数阶O(nlogN)
for(m=1; m<n; m++)
{
i = 1;
while(i<n)
{
i = i * 2;
}
}
空间复杂度
算法的空间复杂度是指算法在执行期间所需要的最大存储空间随问题规模n增大而增长的趋势,它也是一种趋势性描述,最大存储空间使用辅助变量所占用空间大小为衡量指标。
例如:
以下是冒泡排序算法实现。
void BubbleSort(int a[], int len)
{
int i, j, temp;
int flags = 0;
for (j = 0; j < len - 1; j++)
{
for (i = 0; i < len - 1 - j; i++)
{
if (a[i] > a[i + 1])
{
temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
flags = 1;//不是有序的,flags设置为1;
}
}
if (flags == 0)
return;
}
为了实现排序,引入了temp、flags等辅助变量,但它们和问题规模n无关,因此冒泡排序的空间复杂度为O(1)。
常用的空间复杂度度量:
- O(1)
- O(n)
- O(n²)
1、O(n)的空间复杂度:
int[] m = new int[n]
for(i=1; i<=n; ++i)
{
j = i;
j++;
}