什么是复杂度分析
复杂度分析就是分析、统计代码的执行效率和资源消耗。
为什么要用复杂度分析
一般情况下可以通过调试代码监控数据的性能、运行时间、以及其他。但是这种方法有两个缺点:
1、对测试环境的要求
2、对测试数据有要求
复杂度分析种类
时间复杂度
空间复杂度
大O表示法
什么是大O表示法
算法的执行效率,粗略地讲,就是算法代码执行的时间。大O时间复杂度实际上并不具体表示代码真正的执行
时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic timecomplexity),简称时间复杂度。
T(n) = O(f(n))
T(n):代码执行的总时间
n:数据的规模
f(n): 每行代码执行的次数总和
O: 代表执行时间T(n)与f(n)成正比
时间复杂度方法
-
1.只关注循环执行次数最多的一段代码。
首先,大O表示法只是表示一个变化趋势,所以我们常常会忽略掉公式中的常量、低阶、系数,只需要记录一个最大的量级,因为常量这些其实对复杂度的影响并不到甚至有些可以忽略不计。 -
2.加法法则:总复杂度等于量级最大的那段代码的复杂度
总的时间复杂度就等于量级最大的那段代码的时间复杂度。 funtion fn1 () { // 时间复杂度为O(1) for(var i =0; i<=100;i++) { return i } // 时间复杂度为O(n) for(j =0; j <= n; j++) { retrun j } // 时间复杂度为O(n²) for(k =0;k <=n;k++){ for(q =0; q<=n;q++) { return q + k } } } 由1得出的结论,只关注循环最多的那次,所以他的总复杂度也就是量级最大的复杂度 -
3.乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
这种情况一般表示于嵌套调用: function fn1 () { let sum = 0 for( var i = 0; i<=n; i++ ) { sum = i + fn2(i) } } function fn2 () { for( var i = 0; i<=n; i++ ) { sum = i + fn2(i) } }
常见的时间复杂度
- O(1)
O(1)只是常量级时间复杂度的一种表示方法,并不是指只执行了一行代码,只要代码的执行时间不随n的增大而增长,这样代 码的时间复杂度我们都记作O(1)。换句话讲,只要在代码中不存在说有循环、递归语句,无论代码有多长,时间复杂度都是O(1)
-
O(n)
-
O(logn)
-
O(nlogn)
-
O(2的n次方)
-
O(n!)
-
O(n+m) O(n* m)
这种时间复杂度和前面的不一样,这个是由两个不同的数据规模来决定的。 function fn1() { for(var i = 0;i<n;i++ ) { return i } for(var j= 0;j<m;j++) { return j } } 由于n和m都是无法确定的数据,所以他的时间复杂度为O(n+m)
空间复杂度
时间复杂度与空间复杂度类似,时间复杂度是为了看时间随着数据变化的增长趋势,那么空间复杂度是为了看存储空间随着数据的变化的一个变化趋势。原理与时间复杂度一致。