时间复杂度
即执行算法的时间成本
基础时间复杂度
基本操作执行次数:一个循环内的操作次数
时间复杂度=循环次数*每步循环中的操作数
- 例子1:
void function(int n)
{
for(int i=0; i<n; i++)
{
printf("操作1");
printf("操作2");
printf("操作3");
}
}
每个循环要执行3次操作,如果需要执行n个循环,则时间复杂度T(n)=3n。
- 例子2:
void function(int n)
{
for(int i=n; i>1; i/=2)
{
printf("操作1");
printf("操作2");
printf("操作3");
printf("操作4");
printf("操作5");
}
}
总共要进行log2(n)次,每一次循环执行5步操作,所以时间复杂度T(n)=5logn
- 例子3:
void function(int n)
{
printf("操作1");
printf("操作2");
}
执行的时间与n无关,时间复杂度T(n)=2
- 例子4:
冒泡排序中,随着排序次数增加需要的操作减少,为等差数列
void function(int n)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<i; j++)
{
printf("等待");
}
printf("操作2");
}
}
T(n)=0.5n^2+0.5n
渐进时间复杂度
一般用O来表示,即把时间复杂度T(n)简化为一个数量级,用数量级之间的对比会更加直观。
简化过程有如下原则:
- 如果运行时间是常数量级,则用常数1表示
- 只保留时间函数中的最高阶项
- 如果最高阶项存在,则省去最高阶项前面的系数
所以上面四个例子的T(n)分别为:
4. T(n)=O(n)
5. T(n)=O(logn)
6. T(n)=O(1)
7. T(n)=O(n^2)
空间复杂度
即执行算法的空间成本
主要根据问题的规模计算
- 例子1:常量空间
void function(int n)
{
int var = 3;
…
}
存储空间大小固定,和输入规模没有直接的关系,空间复杂度是O(1)
- 例子2:线性空间
void function(int n)
{
int [] arry = new int[n];
…
}
线性集合的空间复杂度可以记为O(n)
- 例子3:二维空间
void function(int n)
{
int [][] arry = new int[n][n];
…
}
二维数组的空间复杂度可以记为O(n^2)
- 例子4:递归空间(例如方法调用栈):我调用我自己
void function(int n)
{
if(n<=1)
{
return;
}
function(n-1)
…
}
空间复杂度与递归深度为正比,也是线性的,空间复杂度可以记为O(n)