算法分析和评价:
在不考虑机器对算法的影响,我们对一个算法主要从时间效率和空间效率两个维度上考虑。
在算法完成功能的前提下,最好是占用的空间少而且执行时间短,事实上,两全其美的算法是不容易设计的,多数的情况是占用空间多时数据处理的步骤就少,反之占用空间少的数据处理的步骤多。
(所以经常会听到空间换时间,时间换空间的说法,包括一些语言执行上也是有这种特性,对反应的速度要求高的更多倾向于接近底层系统的繁重语言例如C,而响应速度没那么高,就选择更加简洁的语言编写)
算法的时间复杂性:
简单理解是就是执行完该算法所用的时间,一般用bigO表示,它是数量级Order的第一个字母。一个算法转换程序后所耗费的时间,主要取决与算法中执行重复执行的次数,即与语句中的频度有关(下面有详细介绍)
(这是学习算法的核心,也是无法绕开的一个问题。)
与算法执行时间相关因素:
- 问题中数据存储的数据结构
- 采用的数学模型
- 设计的策略
- 问题的规模
- 实现算法的设计语言
- 编译算法产生的机器代码的质量
- 计算机执行指令的速度
算法时间衡量方法:
- 事后分析法:指的是将算法用程序实现后,直接执行,看执行时间。缺点很明显:不同算法下时间浮动大,不够准确,工作效率低,也与我们做的算法分析的目的违背的(因此很少用,除非已经到了无可奈何的情况下)
- 事前分析估算法:一个特定的算法“运行工作量”的大小,只依赖与问题的规模(一般用n表示)。算法的时间效率是问题规模的函数,随着问题的规模n的增长,算法执行,时间的增长率和函数f(n)的增长相同:
T(n)就是我们常说的时间复杂度,O是数量级的符。
算法执行时间与原操作执行次数之和成正比
频度:其实就是该语句执行的重复的次数。例如:
for(j =1 ;j<=n;j=j+1){
for(k=1;k<n;k=k+1){
x=x+1;
}
}
k=k+1 x=x+1 频度为n^2
k<n 频度为n(n+1)
j=j+1 k=1 频度为n
j=1 为1
j<=n 频度为n+1
综上所述:时间复杂度3n^2+4n+2
复制代码
虽然上面会有一点点难以理解,但是实际上采用的是 从算法中选取一种对于说研究的问题来说是基本的原操作,以该基本操作在算法中重复执行的次数作为算法运行时间的算法的衡量准则。假设遇到下面多重层次循环结构,按照上面方法就很麻烦了
for(i=1;i<n;i++){
for(j=1;j<n;j++){
for(k=1;k<n;k++){
//输出语句
}
}
}
时间复杂度 为 n^3
复制代码
一般来说我们是直接忽略低阶常数项,直接保留高阶
算法的数量级
为了方便算法之间比较,算法时间复杂度均表示为:
- O(1) 为常数级
- O(logn)对数级
- O(n) 线性级
- O(c^n) 指数级
- O (n!) 阶乘级
时间复杂度是越来越高的,随着n的增长,通过观察曲线的变化,因此尽量不要选择指数级和阶乘级的算法。
算法时间复杂度的最好情况和最坏情况
有时候对于数据的输入也会影响算法,就像一些排序算法,数据的位置也会影响算法的时间复杂度,所以一般来说算法时间复杂度的衡量标准都是指 算法的平均复杂度。