一、概念
算法是对特定问题求解步骤的一种描述;对于一个问题,我们可以使用不同的求解步骤,但是并不是所有的求解步骤都是最好的,我们需要为我们的求解步骤寻找一种最有的解法(不仅仅是通过代码的数量来判断,而是通过运算步骤来进行判定)
二、特性
输入:可以理解为函数的输入参数,可以没有参数,也可以存在有多个参数
输出:至少存在一个输出,否则这个算法是没有意义的
有穷性:运算的步骤(计算机的指令)需要是有限次的,无法停止运行是没有意义的
确定性:算法的每个步骤计算是有明确的意义的,在给定的条件下,输出的结果也是相同的
可行性:算法的每个步骤都是可行可效的(每个步骤都是可以通过有限步骤实现的)
三、算法的衡量
我们对于一个算法的衡量(度量)是有标准的;存在两个维度的判断:时间复杂度和空间复杂度
上面说到的衡量算法的方法都是基于一定规模来看的,往往忽略其处理小规模问题的差异,而是关注在更大规模问题时的表现,即更注重随着规模的增大,其效率的总体变化趋势
四、时间复杂度
随着问题规模n的增长,算法执行时间的增长率和f(n)的增长率相同,称为算法的渐进时间复杂度,简称为时间复杂度
对于上面这句话可以这样理解:假定计算机计算的每个步骤的时间单位是一个固定的,而完成一个算法的执行步骤的多少可以直接等价衡量时间复杂度
为了表示复杂度,可以使用O(),一般称为大O表示法
例:现在我们有一个队列(有n个元素),中间的每个元素都是不一样的,此时需要从中找到一个元素,最好的结果就是第一个元素就是我们所需要的,此时的时间复杂度就是O(1);当然也是存在有最坏的结果,那就是直到找到最后一个元素才找到我们所需要的元素,此时的时间复杂度就是O(n)
通过上面这个简单的例子,可以发现两个影响时间复杂度的因素:
1、问题的规模,规模越大,算法的基本步骤也就越多
2、数据的初始状态,如果一个待处理的数据初始状态就与求解结果相匹配,此时的时间复杂度就是O(1)(上面的例子中,要找的数据就在第一个位置)
**重点**:对于一个算法的时间复杂度的衡量一般存在两种方法:
1、计算所有情况的平均值,例如上面例子的平均时间复杂度n/2
2、计算最坏情况下的复杂度(通常都会使用最坏的复杂度)
五、空间复杂度
对于一个问题,我们不仅仅可以通过计算将问题的结果获取到,还可以通过消耗空间存储的能力,将问题的规模变小,这样就能够换取时间上的便利
对于一个问题,我们可以通过算法不断计算得到一个结果;同时还可以将问题与结果直接映射(键值对)进行存储,这样在获取结果的时候,时间复杂度就为O(1),但是这无疑增加了内存消耗
空间复杂度有以下集中情形:
1、常量空间:O(1),存储的空间是固定的,和输入的规模没有关系
2、线性空间:O(n),存储空间是一个线性集合,这个集合的大小和输入规模是正相关的
3、二维空间:O(n^2),分配的空间是一个二维,这个集合的长度和宽度是规模是正相关的
4、递归空间:O(n),在运行递归代码时,每递归一次,就会专门分配一块栈空间,递归的次数越多,需要的栈空间也就越多,当达到条件时,开始出栈;所需要的内存空间和递归的深度正相关,纯粹的递归操作空间复杂度是线性的,所以这里的空间复杂度是O(n)
六、小结
通常情况下,我们所说的算法的复杂度指的是时间复杂度(内存越来越大,可以空间换时间)