对于学习算法的同志们,少不了对于时间复杂度的学习,在此对时间复杂度的学习进行记录,如有纰漏,尽请评论。
从字面解析,就是一个算法运行的时间,很多小伙伴都想到了把算法程序运行一遍,那么消耗的时间就自然而然的知道了,这种方式是可以的,但是有很多的弊端,很容易受到运行环境的影响,性能的高低相差很大,对使用的数据规模也有关系。所以还是不能完整的去运行它。
这样一种通用的方式就诞生了,「 大O符号表示法 」,在 大O符号表示法中,时间复杂度的公式是: T(n) = O( f(n) ),其中f(n) 表示每行代码执行次数之和,而 O 表示正比例关系,这个公式的全称是:算法的渐进时间复杂度。 这种方式并不是用于来真实代表算法的执行时间的,表示执行时间增长的变化趋势的。
1. 常数阶O(1)
int i = 1;
int j = 2;
++i;
j++;
int m = i + j;
没有循环等复杂结构,它的消耗并不随着某个变量的增长而增长,无论有多长,这个代码的时间复杂度就都是O(1)。
2. 线性阶O(n)
for(i=1; i<=n; ++i)
{
j = i;
j++;
}
for循环里面的代码会执行n遍,因此它消耗的时间是随着n的变化而变化的,这类代码都可以用O(n)来表示它的时间复杂度。
3. 对数阶O(logN)
int i = 1;
while(i<n)
{
i = i * 2;
}
在while循环里面,每次都将 i 乘以 2,乘完之后,i 距离 n 就越来越近了。假设循环x次之后,i 就大于 2 了,此时这个循环就退出了,也就是说 2 的 x 次方等于 n,那么 x = log2^n也就是说当循环 log2^n 次以后,这个代码就结束了。因此这个代码的时间复杂度为:O(logn)
4. 线性对数阶O(nlogN)
for(m=1; m<n; m++)
{
i = 1;
while(i<n)
{
i = i * 2;
}
}
线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。
5. 平方阶O(n²)
for(x=1; i<=n; x++)
{
for(i=1; i<=n; i++)
{
j = i;
j++;
}
}
平方阶O(n²) 就很容易理解了,如果把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 了。