时间复杂度
1. 什么是时间复杂度
就是算法的执行效率。 即算法的执行时间与算法的输入值之间的关系
例
function test(num){
total = 0 ------>假设该行运行时间为t1
for (i = 0 ; i < num ; i++){
total += i ------>假设该行运行时间为t2
}
return total ------>假设该行运行时间为t3
}--------->那么总运行时间为 (t1 + num*t2 + t3)
t1 t3为固定的时间,t2*num是根据num动态变化的,所以整体的时间取决于num
比如num=10000时,就可以忽略t1 t3,故用大O表示法为O(N)
2. 大O表示法
一种粗略的评价计算机算法效率的方法.后面的内容会用到表示效率的方法.
名称来源:使用大写字母O 含义: order of (大约是)
大O表示法实质并不是对运行时间给出实际值,而是表达运行时间是如何受数据项个数所影响
形式为:O()—>括号里是一个数学函数表达式f(N),比如1、logN、N、N^2等,
指明了该算法的耗时/耗空间程度与数据增长量之间的管理,N代表输入数据的量
3. 常见的时间复杂度
O(1) O(logn) O(n) O(nlogn) O(n^2)
大小关系:
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
常见时间复杂度之间的关系(图表):https://www.cnblogs.com/byron0918/p/10544937.html
例子:(以下代码为伪代码,没有var变量,示意而已)
O(1) function O1 (num){
i = num --->t1
j = num * 2 --->t2
return i + j --->t3
} ---> (t1 + t2 + t3)
t 为常数,与num无关,为O(1)
O(logn) function Ologn (num){
i = 1 --->t1
while(i < num){
i = i * 2 --->t2
}
return i --->t3
} ---> (t1 + ?*t2 + t3)
因为while循环里面不是每次加一,所以循环总时间tx不再是num*t2
假设要循环x次能跳出循环,则2^x = num,所以x = log2(num)
每一次循环时间为t2,循环总时间 tx=t2 * log2(num)
常量去除后简写为 O(logn)
O(n) function On (num){
total = 0 --->t1
for (i = 0 ; i < num ; i++){
total += i --->num*t2
}
return total --->t3
} ---->(t1 + num*t2 + t3)
for循环,循环时间为 num*t2,不考虑常量t2,即num所以为O(n)
O(n+m) function On (num1,num2){
total = 0 --->t1
for (i = 0 ; i < num1 ; i++){
total += i --->num*t2
}
for (j = 0 ; j < num2 ; j++){
total += j --->num*t3
}
return total --->t4
} ---->(t1 + num*t2 + num*t3 + t4)
for循环两次,同时因为是并列的循环,所以时间应该是两者相加,故同上,所以为O(n+m)
O(nlogn) function Onlogn (num1,num2){
total = 0
j = 0 --->t1
for (i = 0 ; i < num1 ; i++){
while(i < num2){
total += i + j
j = j * 2 --->t2
}
}
return total --->t3
} ---> (t1 + ?*t2 + t3)
双重嵌套循环,里面一层是O(logn),外面一层是O(n),相乘即为O(nlogn)
O(n2) function On2 (num){
total = 0 --->t1
for (i = 0 ; i < num ; i++){
for (j = 0 ; j < num ; j++){
total += i + j --->num*t2
}
return total --->t3
} ---->(t1 + num*t2 + t3)
双重嵌套循环,里面一层是O(n),外面一层是O(n),相乘即为O(n2)
先看是否有循环,没有循环基本是就是O(1),再看循环是否嵌套,分情况考虑
4. 常用数据结构增删查时间复杂度
数据结构 | 根据关键字查找 | 根据索引查找 | 插入 | 删除 |
---|---|---|---|---|
数组 | O(n) | O(1) | O(n) | O(n) |
有序数组 | O(logn) | O(1) | O(n) | O(n) |
链表 | O(n) | O(n) | O(1) | O(1) |
有序链表 | O(n) | O(1) | O(n) | O(n) |
双向链表 | O(n) | O(1) | O(n) | O(n) |
二叉树(一般情况) | O(logn) | - | O(logn) | O(logn) |
二叉树(一般情况)最坏情况 | O(n) | - | O(n) | O(n) |
平衡树 | O(logn) | O(logn) | O(logn) | O(logn) |
排序二叉树 | O(logn)~O(n) | O(logn)~O(n) | O(logn)~O(n) | O(logn)~O(n) |
哈希表 | O(1) | - | O(1) | O(1) |
空间复杂度
1. 什么是空间复杂度
算法的存储空间与算法的输入值之间的关系
空间复杂度