算法素颜(第3篇):KO!大O——时间复杂度
阅读本文需要5分钟
引言
在本系列第1篇《走下神坛吧!算法》中提到了:计算复杂度分为时间复杂度与空间复杂度。本篇文章来讲讲时间复杂度。
如何度量时间复杂度
时间复杂度由所消耗的时间决定。所消耗的时间由硬件与软件共同决定。在同一硬件条件下,所消耗的时间由软件决定。
通常意义上的算法指的是软件算法,所以在谈论时间复杂度时,聚焦软件的时间开销。
软件的时间开销 = 软件各组成部分的时间开销之和。
软件最基本的组成部分是语句(或者微观意义下的指令)。
注:因为在同一硬件条件、特定的编程语言环境下,基本语句由多少条指令构成、运行的模式都是固定的,所以直接以语句作为基本考察单位即可。
整体等于各部分之和
对大部分编程语言而言,基本语句无外乎以下两种:
1. 读写语句
2. 比较语句
注:条件语句(if-else)、循环语句(while/for)在这里都不算基本语句,而被看作复合语句。
原因如下:
对于条件语句,一般形式如下:
// 相当于先运行比较语句
// (xxx<->true),
// 再根据比较结果运行aaa
if (xxx) { aaa;}
// 相当于先运行比较语句
// (xxx<->true),
// 再根据比较结果运行bbb
else if (yyy) { bbb; }
对于循环语句,一般形式如下:
(为简单起见,这里只做while的示例,其他循环类型依此来推)
// 相当于先运行比较语句(xxx<->true),
// 再根据比较结果运行aaa
// 然后运行比较语句(xxx<->true),
// 判断是否出循环体
while (xxx) { aaa; }
将基本语句的时间开销看作“单位1”,那么整个程序的时间开销就是所有这些“单位1”之和。
推论3.1:
假设程序结构L由n个子结构Li组成,即:
那么运行L的整体时间开销T(L)为:
T(L) = f(n)
来看几个例子:
// 赋值语句、基本语句,
// 时间开销=1
int i = 10;
// 比较语句、基本语句,
// 时间开销=1
a > b;
// 条件语句、复合语句
// 包含一条比较语句和一条赋值语句
// 时间开销=1+1=2
if (a > b) { c= 9; }
再来看一个复杂一点的:
int buf_size = input_array.size;
for (i = 1; i < buf_size; i++) {
p = q + 1;
if (p > i) { break; }
}
整个程序结构L由一条赋值语句(记为J)和一个循环体(记为K)组成,
则:L = J + K (式3.1)
循环体K由一条赋值语句X和一个条件语句Y组成,循环次数n在最坏情况下等于buf_size。所以在最坏情况下:
K = n(X + Y) (式3.2)
代入式3.1,得到:L = J + n(X+Y) (式3.3)
根据推论3.1,从式3.3可得到:
T(L) = T(J) + T(n(X + Y)) = T(J) + nT(X + Y) = T(J) + n(T(X) + T(Y)) (式3.4)
因为J, X为赋值语句,属于基本语句,所以T(J) = T (X) = 1
因为Y为简单条件语句,T(Y) = 2
如果buf_size = 10,那么n = 10
将T(J), T(X), T(Y), n代入式(3.4)得到: T(L) = 1 + 10 x (1+2) = 31
从上面的例子可以看出:
(i) n不同,T(L)的值就不同;
(ii) n越大,T(L)的值也越大;
(iii) n等于buf_size,后者是由输入input_array的规模决定的
所以,可以看出:T(L)与输入规模相关。用数学的语言来描述就是:整体时间开销是一个关于输入规模因子的函数。
用数学表达式表示就是:T(L) = f(n)
T= f(n)的现实意义是什么
f(n)既然是个函数,那么由高中数学知识可知,f(n)的形式有很多种,如:
不同形式的f(n),在n增加的时候,T增加的速度不同。
每一种f,对应一种算法,所以:
推论3.2:
T表示在同等输入规模(即n一定)的情况下,不同算法的时间开销。
T的增加速度越快,对应算法的时间开销越大,也就表示该算法越复杂。
“两种算法的复杂度在一个量级”到底是个什么鬼
考虑考虑 T1=2n和 T2=n 。
很显然,在n固定的情况下, T1/T2=2 。即:同等输入规模下,第一种算法的时间开销是第二种算法时间开销的2倍。
这种复杂度关系总是常数倍的,即使n取无穷大也是。用数学语言表示就是:
从而,我们得到一个关键结论:
推论3.3:
两种算法的复杂度在同一量级等价于
其中C是常数
聪明的你肯定会问到:如果n趋向无穷大的时候,T1/T2不是常数呢?
如果不是常数,那么通常是一个关于n的表达式,随着n的增加,值也增加。这表示T1/T2也将趋向无穷大。用数学术语表达就是“发散”。
我们称这种况下,两种算法不在同一复杂度量级。
推论3.4:
算法1比算法2的复杂度量级高等价于
大O登场
通常比较算法复杂度,只用比较量级即可。量级用O()表示。
O()定义:
(i) 如果算法T1与算法T2的复杂度在同一量级,那么O(T1) = O(T2)
(ii) 如果算法T1比算法T2的复杂度量级高,那么O(T1) > O(T2)
(iii) 如果算法T1比算法T2的复杂度量级低,那么O(T1) < O(T2)
比较T1与T2的复杂度量级:
根据推论3.3得到:T1与T2处于同一复杂度量级。
根据上述O()的定义:O(T1) = O(T2)
这里其实蕴含了一个非常实用的结论:
推论3.5:
算法复杂度的大O表示可以简化为该算法最高阶部分的复杂度的大O表示。
根据高等数学知识,我们可以得到:
总结
大O表示法最早由德国数论学家保罗·巴赫曼(英语:Paul Bachmann)在其1892年的著作《解析数论》(Analytische Zahlentheorie)首先引入的。
而这个记号则是在另一位德国数论学家艾德蒙·朗道(英语:Edmund Landau)的著作中才推广的,因此它有时又称为朗道符号(Landau symbols)。
大部分的算法或者复杂度理论的书籍,在介绍大O时,要么过于数学形式化,要么过于感性非严格化。
本篇文章旨在用最少的数学知识、启发式行文方式、全新的原创视角,为读者构建一个清晰、严格的时间复杂度概念。
相信看到这里,以后再面对时间复杂度和大O,你一定信心满满了:)
本原创系列同步在以下自媒体上更新,敬请关注:
头条:
https://www.toutiao.com/i6672014755760177668/
简书:
https://www.jianshu.com/u/37a695e1c9c2
知乎:
https://www.zhihu.com/people/cubiezhou2017/activities
END
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【入坑JAVA安全】JAVA反射机制
- 小妹妹,我想握着你的手,不为别的,只为给你讲清楚CVE-2020-5902
- 不是吧?阿sir!周末你就不学习了吗?
- 灰盒方式通关WebGoat8
- 调试支付宝脱机认证接口遇到的问题总结
- 换一种姿势挖掘任意用户密码重置漏洞
- 表哥,有没有XMLDecoder反序列化的案例?
- 不得不说,minigui真的很坑
- 树的遍历总结
- ggplot2|详解八大基本绘图要素
- LDheatmap|SNP连锁不平衡图(LD)可视化,倒三角图?
- Oracle 表分区笔记
- Java并发编程
- 让终端支持https,移植OpenSSL和libcurl到嵌入式linux,遇到的问题总结
- ComplexHeatmap|根据excel表绘制突变景观图(oncoplot)