茶艺师学算法打卡1:复杂度分析
写在前面的话
算法,是一门技术。
学习笔记
1.如何看一段程序(或者算法)的运行效率,用不着等到测试,在事先使用复杂度分析就能对情况有个大致的摸底。
2.算法的复杂度分析,分时间复杂度与空间复杂度,分析随着数据规模的增大,程序运行的耗时(或者空间使用)变化关系。
3.我们习惯用的,是 大O分析法 。其中时间复杂度,就是关注某个算法的运行次数函数的最高阶,并不看常量。
4.专栏里写到 大O 是渐进复杂度,其实这是专栏老师给我们读者的手下留情。其中更学术的叫法为 渐进记号 。 大O 也只是其中的一个,他的“伙伴”还有(不限于): Θ(Theta)记号 、 Ω(Omega)记号 、小o记号 、ω记号。他们的关系如下图
5.专栏里还介绍了更加“刁钻”的时间复杂度分析法,它们就是最佳时间复杂度、最坏时间复杂度、平均时间复杂度、均摊时间复杂度。
| 名称 | 特点 | 计算方法 |
|---|---|---|
| 最佳时间复杂度 | “一算就出结果” | |
| 最坏时间复杂度 | “全部算完才出结果” | |
| 平均时间复杂度 | 需要考虑数据被算到的概率 | 概率+加权平均数 |
| 均摊时间复杂度 | 特殊的平均时间复杂度,不必考虑概率 | 均摊分析法 |
结语
在这里,我介绍一个案例,它带给我了一点“算法效率的震撼”。
众所周知,有这么两个排序算法,插入排序和归并排序,前者的时间复杂度为 ,后者的为 。
找来了两台电脑 A 和 B ,每台电脑都要排序一个具有1000万个数的数组。
A 是好电脑,每秒能执行百亿条指令,它将使用插入排序算法。
B 每秒仅能执行1000万条指令,它用归并排序算法。
为了让这次比赛更具戏剧性,某天才程序员直接给 A 用机器语言编码插入排序,保证了排序 n 个数字仅需 条指令。而 B 仅仅是使用带着低效编译器的高级语言( Python 表示不背这个锅)实现的归并排序,执行完需要 条指令。
| 机器名称 | 机器处理速度 | 所用算法 | 算法时间复杂度 | 执行所需指令数 |
|---|---|---|---|---|
| A | 百亿 | 插入排序 | ||
| B | 1000w | 归并排序 |
在这里你也要不要猜猜是谁先运行完?
A 有着比 B 快1000倍的性能,然而实际算下来,A 需要
而 B 需要
这里看到,就算是机器烂,只要选对了所使用的算法,还是能高效完成任务的。
而学好复杂度分析,就是我们将来选择算法的“火眼金睛”。
这么重要的技能,我们不学起来?