算法对于敲代码的应该都听过,不管是复杂的还是简单的,衡量算法效率的两个重要指标就是时间复杂度和空间复杂度。
时间复杂度:评估执行程序所需的时间。可以估算出程序对处理器的使用程度。空间复杂度:评估执行程序所需的存储空间。可以估算出程序对计算机内存的使用程度。
空间复杂度:对一个算法在运行过程中临时占用存储空间大小的量度。查了很多,对于计算空间复杂度还是没有一个很好的理解,因为有些说需要把算法内部使用的全局变量算在内,有些说只需要把算法内部变量算在内,有些说需要循环几次,每一次的临时变量需要叠加算,有些又说临时变量会被销毁,还是只算一个。所以我们只要记住,空间复杂度就是这个算法运行过程中临时占用的内存。
时间复杂度:你可以简单理解算法运行所需要的时间,我们一般会以牺牲空间复杂度来实现时间复杂度最优。如果单纯以时间来衡量时间复杂度不是很准确,因为相同算法在不同环境或者不同数据下运行时间是不一样的。所以,时间复杂度一般用大O符号表示法。
大O表示法有三个规则:
1.用常数1取代运行时间中的所有加法常数
2.只保留最高阶项
3.去除最高阶的常数
常数阶:
var a = 1;//执行1次
var b = 2;//执行1次
console.log(a + b);//执行1次
比如这样的代码,每一句都是执行一次,加起来是三次,套用规则1,这段代码时间复杂度为O(1)。
线性阶:
var a = 1;//执行1次
for(var i = 0; i < n;i++){
console.log(i)//执行n次
}
总共执行了n+1次,套用规则,保留高阶项,去除高阶常数,所以时间复杂度是O(n)。
对数阶:
var a = 1;//执行1次
while (a < n){
a *= 2; //执行了logn次
}
这段代码while里面要判断执行次数,假设执行次数是x那么要成立2^x > n,所以得出来的执行次数就是logn(这是基本的数学了,不懂的话我也无能为力)。应该有人会觉得log的底数是10,而我们这边底数是2,但在算法里面,我们只会用数学的方法把n无限大去比较,所以不管底数是多少,算法的时间复杂度的增长与处理数据多少的增长的关系是一样的。套用规则,这段代码执行次数logn + 1,保留高阶项,去除高阶常数,所以时间复杂度是O(logn)。
平方阶:
for (var i = 0; i < n; i++) {
// 语句执行n次
for (var j = 0; j < m; j++) { 语句执行m次
console.log(i + j); // 语句执行n*m次
}}
同样的,这边执行次数是n*m,用数学的方式n和m趋于无穷大的时候,n≈m,于是执行次数就是n2,所以时间复杂度是O(n2)。当然还有n的三次方、四次方等。
算法还有很多很多的时间复杂度,你要是数学学得好,你就可以找出更多的时间复杂度,本人要是高中时候还能多找几个,现在只能理解这几个了。
而时间复杂度也是能比较的,单以这几个而言:
O(1)<O(logn)<O(n)<O(n²)<O(n³)
一个算法执行所消耗的时间理论上是不能算出来的,我们可以在程序中测试获得。我们不可能也没必要对每个算法进行测试,我们通过类似上面的方法,就能大概的比较出算法的执行效率。
分享时间复杂度这个概念只是想让大家了解一下我们写的一些代码执行效率是可以比较的,时间复杂度也并不能单纯的以上面单个来看,经常会组合夹杂着出现。
Coding 个人笔记