数据结构和算法本身解决的是“快”和“省”的问题,即如何让代码运行得更快,如何让代码更节省存储空间。只要讲到数据结构与算法,就离不开复杂度分析。
复杂度包括时间复杂度、空间复杂度。
时间复杂度分析:
时间复杂度的全称是渐近时间复杂度,表示算法的执行时间与数据规模之间的增长关系。
大O表示法:
示例代码:
//求1,2,3,...,n的和
int sum(int n)
{
int s = 0;
int i = 1;
for(;i <= n; ++i)
{
s = s+i;
}
return s;
}
假设每行代码执行的时间都一样,为t,第2、3行代码分别需要1t的执行时间,第4、5行都执行了n次,所以需要2n*t的执行时间,所以T(n) = (2n+2)t,所以,所有代码的执行时间T(n)与每行代码的执行次数n成正比。
大O表示法:T(n) = O(f(n)),T(n):代码执行的总时间,f(n):每行代码执行的次数总和,O表示T(n) 与f(n)表达式成正比。
大O时间复杂度表示法实际上并不具体表示代码真正执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫做渐近时间复杂度,简称时间复杂度。
公式中的低阶、常量、系数等部分并不左右增长趋势,所以都可以忽略,在记录的时候只需要记录一个最大量级,所以,刚才的时间复杂度表示为O(n)。
时间复杂度分析方法:
1.只关注循环执行次数最多的一段代码;
2.加法法则:总复杂度等于量级最大的那段代码的复杂度;
3.乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积。
最好、最坏情况时间复杂度:
最好情况时间复杂度就是在最理想的情况下,执行这段代码的时间复杂度;同理,最坏情况时间复杂度就是,在最糟糕的情况下,执行这段代码的时间复杂度。
平均情况时间复杂度:
简称平均复杂度。
均摊时间复杂度
常见时间复杂度量级:
1.常量级:O(1)
一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行代码,其时间复杂度也为O(1).
2.O(logn)\O(nlogn)
在采用大O标记复杂度的时候,可以忽略系数,所以在对数阶时间复杂度的表示方法里,我们忽略对数的底数,常见的归并排序、快速排序的时间复杂度都是O(nlogn)。
3.O(m+n)\O(m*n)
代码的复杂度由两个数据的规模来决定,在无法实现评估m和n谁的量级大时,不能简单利用加法法则,省略掉其中一个,所以要加\乘到一起。
空间复杂度分析:
空间复杂度的全称是渐近空间复杂度,表示算法的存储空间与数据规模之间的增长关系。