老规矩,要学习算法还是要先了解以下几个问题:
- 什么是算法?
- 算法有什么用?
- 如何选择算法?
算法的基本概念
还记得之前用C++刷算法题目时,除了各种STL(标准模板库)里已经已经写好的各种数据结构头文件外,还有一个头文件用到的频率也很高,那就是algorithm(算法)头文件。尤其是遇到排序题目,基本上都会先用里面的sort()函数。
算法(Algorithm)是对特定问题求解的一种描述,是指令的有限序列。 很懵对吧?那我换种说法:算法就是求解问题的有限次步骤。 还不懂也没关系,概念基本是不会考的。
接下来,再说一下算法的五个特性。
- 有穷性:步骤要有限次,且每一步也要在有限时间内结束。
- 确定性:每条指令一定要准确性,确保相同的输入,一定有相同的输出。
- 可行性:描述的操作可以通过已经实现的基本运算执行有限次来实现。
- 输入:一个算法有零个或多个输出。注意哦,是可以没有输入的。
- 输出:一个算法有有一个或多个输出。必须要有输出!!
好了,上面这一堆也不会考的,但是我们还是要了解一下的。
一个好的算法应该要满足以下几点目标:
- 正确性:能够正确地解决问题。
- 可读性:要具有好的可读性,方便人们理解。如果一个算法只有写它的人才能够读懂他,那是没有意义的。
- 健壮性:针对非法输入,应该有适当的处理,而不会产生乱七八糟的输出,更不应该影响整个系统。
- 效率与低存储量需求:效率是指算法执行的时间,存储量需求是指算法执行过程中所需的最大存储空间,这两者都与问题的规模。
那么如何选择好的算法呢?优先考虑前三者,但是前三者没有太大差别的情况下,那就看第四点。一个算法运行时间短,一个算法运行时间长,肯定闭着眼睛也选时间短的呀。空间方面也是一样的选择。
那假如一个算法运行时间短,但是需要空间大;另一个算法运行时间长,但是需要空间小。那该如何选择呢? 时间和空间,我们是更侧重时间的。因为随着科技的发展,硬件越来越便宜,成本越来越低。所以空间换时间是现在算法中经常会出现的一种做法。
那我们如何度量一个算法的效率呢?通过时间复杂度和空间复杂度。
算法效率的度量
时间复杂度
在了解时间复杂度之前,先来了解几个概念:
频度:一个语句在算法中被重复执行的次数。
算法中所有语句的频度之和,被称为T(n),它是关于问题规模n的函数
时间复杂度就是分析T(n)的数量级。
基本运算:算法最深层循环内的语句。 它的频度跟T(n)同数量级,因此主要分析基本运算的频度f(n)来分析时间复杂度。
复杂的时间复杂度记为T(n)=O(f(n)),O的含义就是T(n)的数量级。
最坏时间复杂度是指在最坏情况下,算法的时间复杂度。
平均时间复杂度是指所有可能输入实例在等概率出现的情况下,算法的期望运行时间
最好时间复杂度是指在最好情况下,算法的时间复杂度。
一般总是考虑的时间复杂度是最坏时间复杂度。
时间复杂度的计算遵循两条规则:
- 加法规则:T(n)=O(f(n))+O(g(n))=O(max(f(n),g(n))) 取最大者
- 乘法规则:T(n)=O(f(n))*O(g(n))=O(f(n)*g(n)) 取两者之积
常见的渐进时间复杂度为