注:截图转自王卓数据结构教学视频
算法和算法分析
算法的定义
对特定问题求解方法和步骤的一种描述,它是指令的有限序列。其中每个指令表示一个或多个操作。
算法的描述
自然语言:英文、中文
流程图:传统流程图、NS流程图
伪代码:类语言:类C语言
程序代码:C语言程序、Java语言程序……
算法与程序
1、算法是解决问题的一种方法或一个过程,考虑如何将输入转换成输出,一个问题可以有多种算法。
2、程序是用某种程序设计语言对算法的具体实现。
程序=数据结构+算法
数据结构通过算法实现操作
算法根据数据结构设计程序
算法特性:一个算法必须具备以下五个重要特性
1、有穷性:一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成。
2、确定性:算法中的每一条指令必须有确切的含义,没有二义性,在任何条件下,只有唯一的一条执行路径,即对于相同的输入只能得到相同的输出。
3、可行性:算法是可执行的,算法描述的操作可以通过已经实现的基本操作执行有限次来实现。
4、输入:一个算法有零个或多个输入。
5、输出:一个算法有一个或多个输出。
算法设计的要求
1、正确性
2、可读性
3、健壮性
4、高效性
一个好的算法首先要具备正确性,然后是健壮性,可读性,在几个方面都满足的情况下,主要考虑算法的效率,通过算法的效率高低来评判不同算法的优劣程度。
算法效率以下两个方面来考虑:
1、时间效率:指的是算法所耗费的时间;
2、空间效率:指的是算法执行过程中所耗费的存储空间。
时间效率和空间效率有时候是矛盾的。
算法时间效率的度量
算法时间效率可以用依据该算法编制的程序在计算机上执行所消耗的时间来度量。
两种度量方法:
1、事后统计:
将算法实现,测算其时间和空间开销。
缺点:编写程序实现算法将花费较多的时间和精力;所得实验结果依赖于计算机的软硬件等环境因素,掩盖算法本身的优劣。
2、事前分析:
对算法所消耗资源的一种估算方法。
事前分析方法:
一个算法的运行时间是指一个算法在计算机上运行所消耗的时间大致可以等于计算机执行一种简单的操作(如赋值,比较,移动等)所需的时间与算法中进行的简单操作次数乘积。
算法运行时间 = 一个简单操作所需的时间 X 简单操作次数
也即算法中每条语句的执行时间之和
每条语句执行一次所需的时间,一般是随机器而异的。取决于机器的指令性能、速度以及编译的代码质量。是由机器本身软硬件环境决定的,它与算法无关。
所以,我们可假设执行每条语句所需的时间均为单位时间。此时对算法的运行时间的讨论就可转化为讨论该算法中所有语句的执行次数,即频度之和了。
这就可以独立于不同机器的软硬件环境来分析算法的时间性能了。
例如:两个nXn矩阵相乘的算法可描述为:
我们把算法所消耗的时间定义为该算法中每条语句的频度之和,则上述算法的时间消耗T(n)为:
为了便于比较不同算法的时间效率,我们仅比较它们的数量级
例如:两个不同的算法,时间消耗分别是:
若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则成f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),则称O(f(n))为算法的渐进时间复杂度(O是数量级的符号),简称时间复杂度。(order)
那么对于刚刚求解矩阵相乘问题,算法耗费时间:
一般情况下,不必计算所有操作的执行次数,而只考虑算法中基本操作执行的次数,它是问题规模n的某个函数,用T(n)表示。
算法时间复杂度定义
注:以上截图均转自王卓数据结构教学视频
基本语句重复执行的次数:
1、算法中重复执行次数和算法的执行时间成正比的语句
2、对算法运行时间的贡献最大
3、执行次数最多
问题规模:
n越大算法的执行时间越长:
1、排序:n为记录数
2、矩阵:n为矩阵的阶数
3、多项式:n为多项式的项数
4、集合:n为元素个数
5、树:n为树的结点个数
6、图:n为图的顶点数或边数
分析算法时间复杂度的基本方法
类似高等数学的极限。
1、找出语句频度最大的那条语句作为基本语句
2、计算基本语句的频度得到问题规模n的某个函数f(n)
3、取其数量级用符号"O"表示
举例:
请注意:有的情况下,算法中基本操作重复执行的次数还随问题的输入数据集不同而不同
算法时间复杂度
1、最坏时间复杂度:指在最坏情况下,算法的时间复杂度。
2、平均时间复杂度:指在所有可能输入实例在等概率出现的情况下,算法的期望运行时间。
3、最好时间复杂度:指在最好情况下,算法的时间复杂度。
一般总是考虑在最坏情况下的时间复杂度,以保证算法的运行时间不会比它更长。
对于复杂的算法,可以将它分成一个容易估算的部分,然后利用大O加法法则和乘法法则,计算算法的时间复杂度。
算法时间效率的比较
1、当n取得很大时,指数时间算法和多项式时间算法在所需时间上非常悬殊。
渐进空间复杂度
空间复杂度:算法所需储存空间的度量
算法要占据的空间
算法本身要占据的空间,输入/输出,指令,常数,变量等。
算法要使用的辅助空间