>[success] # 复杂度分析
~~~
1.首先要掌握一个数据结构与算法中最重要的概念——复杂度分析
~~~
>[info] ## 大 O 复杂度表示法
~~~
1.概念:算法的「执行时间」与每行代码的「执行次数」成正比'T(n) = O(f(n))',
其中T(n)表示算法执行总时间,f(n)表示每行代码执行总次数,而n往往表示数据的规模。
1.1.'T(n)' -- 算法执行总时间
1.2.'f(n)' -- 表示每行代码执行的次数总和
1.3.'n' -- 数据的规模的大小
2.大O符号(Big O notation)是用于描述函数渐进行为的数学符号。更确切地说,
它是用另一个(通常更简单的)函数来描述一个函数数量级的渐近上界,举个例子:
'T(n) = 4n^2 - 2n + 2,当 n 增大时,n^2; 项将开始占主导地位,而其他各项可以被忽略'
上面的内容就可以表示为'T(n)=O(4n^2)'
理解:就是O 可以理解我们默认一个常量无穷大的时候,只关心他的主导条件,忽略其他与它
相比可以忽略的条件 -- 也就是无穷大渐近
~~~
>[danger] ##### 通过代码案例理解(一)
~~~
1.下面代码是前端的代码,代码实现的是累加求和。
~~~
~~~
function cal(n) {
let sum = 0 // 运行时间 1 个unit_time
let i = 1 // 运行时间 1 个unit_time
for(;i<=n;i++){ // 运行时间 n 个unit_time
sum = sum + i // 运行时间 n 个unit_time
}
return sum
}
console.log(cal(10)) // 55
~~~
* 分析这段代码的复杂程度
~~~
1.参数'n'对应 -- 上面概念讲解里的 '数据的规模的大小'
2.把每行运行时间默认为 1 个unit_time
3.像上面的代码'i' 和 'sum' 都是变量,只会执行一次因此它俩的时间效率分别都是1 个unit_time
,for循环的时间效率是根据'n'的长度来决定的因此是 n 个unit_time
4.所以上面的代码总时长是 '2*unit_time+n*unit_time+n*unit_time'整理可得:
(2n+2)*unit_time
5.用大 O 复杂度表示法,取'无穷大渐近'T(n) = O(n)
~~~
>[danger] ##### 通过代码案例理解(二)
~~~
1.分析下面案例,主要分析的是内层循环代码,因为我们都知道外层循环一次等于内层循环
一遍,因此下面代码中的外层次数是'n',外层每循环一次内层就给来一遍因此内层循环次数就是
'n*n'
2.整理一下,下面代码的执行时间 '3*unit_time + 2n*unit_time +2n^2unit_time'合并可得:
'T(n) = (2n2+2n+3)*unit_time'
3.用大 O 复杂度表示法,取'无穷大渐近'T(n) = O(n^2)
~~~
~~~
int cal(int n) {
int sum = 0; // 1 个unit_time
int i = 1; // 1 个unit_time
int j = 1; // 1 个unit_time
for (; i <= n; ++i) { // n 个unit_time
j = 1; // n 个unit_time
for (; j <= n; ++j) { // n^2 个unit_time
sum = sum + i * j; // n^2 个unit_time
}
}
}
~~~
>[danger] ##### 简单总结
~~~
1.所有代码的执行时间 T(n) 与每行代码的执行次数 n 成正比
2.大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示
代码执行时间随数据规模增长的变化趋势,所以,也叫作'渐进时间复杂度'
简称'时间复杂度'
3.当 n 很大时公式中的低阶、常量、系数三部分并不左右增长趋势,所以都可以忽略。
我们只需要记录一个最大量级就可以了,如果用大 O 表示法表示刚讲的那两段代码的
时间复杂度,就可以记为:T(n) = O(n); T(n) = O(n^2),这是大O符号的在数学中的含义
无穷大
~~~
- 接触数据结构和算法
- 数据结构与算法 -- 大O复杂度表示法
- 数据结构与算法 -- 时间复杂度分析
- 最好、最坏、平均、均摊时间复杂度
- 基础数据结构和算法
- 线性表和非线性表
- 结构 -- 数组
- JS -- 数组
- 结构 -- 栈
- JS -- 栈
- JS -- 栈有效圆括号
- JS -- 汉诺塔
- 结构 -- 队列
- JS -- 队列
- JS -- 双端队列
- JS -- 循环队列
- 结构 -- 链表
- JS -- 链表
- JS -- 双向链表
- JS -- 循环链表
- JS -- 有序链表
- 结构 -- JS 字典
- 结构 -- 散列表
- 结构 -- js 散列表
- 结构 -- js分离链表
- 结构 -- js开放寻址法
- 结构 -- 递归
- 结构 -- js递归经典问题
- 结构 -- 树
- 结构 -- js 二搜索树
- 结构 -- 红黑树
- 结构 -- 堆
- 结构 -- js 堆
- 结构 -- js 堆排序
- 结构 -- 排序
- js -- 冒泡排序
- js -- 选择排序
- js -- 插入排序
- js -- 归并排序
- js -- 快速排序
- js -- 计数排序
- js -- 桶排序
- js -- 基数排序
- 结构 -- 算法
- 搜索算法
- 二分搜索
- 内插搜索
- 随机算法
- 简单
- 第一题 两数之和
- 第七题 反转整数
- 第九题 回文数
- 第十三题 罗马数字转整数
- 常见一些需求
- 把原始 list 转换成树形结构