复杂度分析(渐进时间和空间复杂度)
- 复杂度分析解决的问题:
在不使用事后统计法(通过在机器上跑代码来获得结论,难以控制变量)来分析代码执行效率的情况下,使用复杂度分析来分析算法执行效率- 大O时间复杂度(渐进时间复杂度):表示代码执行时间随随数据规模增长的变化趋势
T(n)= O(f(n))
T(n)表示代码的执行时间;n表示数据规模的大小
f(n)代表每行代码执行的次数总和
O表示成正比
时间复杂度分析
1.只关注循环执行次数最多的一行代码
大O只是表示一种变化趋势。忽略掉公式中的常量,低阶,系数,只需要记录一个最 大阶的量级就可以了
2.加法法则:总复杂度等于量级最大的那段代码的复杂度
循环执行100此也只是一个常量级执行时间,与n规模无关
只要是一个已知数,跟n无关,是常量级的执行时间
3.乘法法则:嵌套的时间复杂度等于嵌套内外代码复杂度的乘积
- 复杂度量级分为:多项式量级和非多项式量级
- 非多项式量级:指数阶和阶乘阶
- 数据规模n越来越大,非多项式量级算法会急剧增加,求解问题时间会无限增长,所以是非常低效的算法
- O(1)
常量级时间复杂度,非执行了一行代码。
代码的执行时间不随n的增大而增大,就为O(1)。不存在循环语句和递归算法,上万行代码也是常量级。- 对数阶和对数的倍数阶
while (i<n){
i*=2;
}
2的i次方等于n,所以i就等于二为底的对数阶
忽略底数,通称对数阶
在对数阶上加上循环,循环几次就是几倍
归并,快排就是n倍的对数阶
- 加法和乘法(两个未知的数据规模m和n)
两个不同的数据规模m和n,只能相加,不能取最大规模。因为无法判断谁的规模大
- 空间复杂度
看申请的空间大小
int[] x = new int[10];
这个的空间复杂度为O(1),如果换为n,就是n了。
越高阶复杂度的算法,执行效率越低
从低到高:1,对数,你,对数的n倍,平方
- 最好情况时间复杂度
在最好的情况下的时间复杂度,循环次数最少的
- 最坏情况时间复杂度
在最复杂情况下的时间复杂度
- 平均情况时间复杂度
复杂度的加权平均值,或者期望时间复杂度
- 均摊时间复杂度
对一个数据进行一组连续的操作中,大部分情况下时间复杂度都很低,只有个别的情况下时间复杂度很高,而且这些操作之间存在前后连贯的时序关系,这个时候,我们就可以将这一组操作放在一块儿分析,看是否能将较高时间复杂度那次操作的耗时,平摊到其他时间复杂度较低的操作上。而且,在能够应用均摊时间复杂度分析的场合,一般均摊时间复杂度就等于最好情况时间复杂度。