目录
1.算法,什么是好算法?
算法定义:对特定问题求解方法和步骤的一种描述,它是指令的有限序列。其中每个指令表示一个或多个操作。算法是解决问题的一种方法或一个过程,考虑如何将输入转换成输出,一个问题可以有多种算法。
程序:是用某种程序设计语言对算法的具体实现。
程序=数据结构+算法,数据结构通过算法实现操作,算法根据数据结构设计程序。
算法特性:一个算法必须具备以下五个重要特性:
(1)有穷性:一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成。
(2)确定性:算法中的每一条指令必须有确切的含义,没有二义性,在任何条件下,只有唯一的一条执行路径,即对于相同的输入只能得到相同的输出。
(3)可行性:算法是可执行的,算法描述的操作可以通过已经实现的基本操作执行有限次来实现。
(4)输入:一个算法有零个或多个输入。
(5)输出:一个算法有一个或多个输出。
算法设计的要求:正确性,可读性,健壮性(鲁棒性),高效性;
2.算法的效率-时间复杂度
在以上几个都满足的条件下,主要考虑算法的效率。
算法效率以下两个方面来考虑:
1.时间效率:指的是算法所耗费的时间;
2.空间效率:指的是算法执行过程中所耗费的存储空间。
时间效率和空间效率有时候是矛盾的。
算法的时间效率可以用依据该算法编制的程序在计算机上执行所消耗的时间来度量。事前分析/事后度量;
算法时间效率的事前分析方法:一个算法的运行时间是指一个算法在计算机上运行所耗费的时间大致可以等于计算机执行一种简单的操作(如赋值、比较、移动等)所需的时间与算法中进行的简单操作次数乘积。
算法运行时间=一个简单操作所需的时间×简单操作次数
也即算法中每条语句的执行时间之和:
算法运行时间=每条语句的执行次数(又称语句频度)×该语句执行—次所需的时间
简化:每条语句执行一次所需的时间,一般是随机器而异的。取决于机器的指令性能、速度以及编译的代码质量。是由机器本身软硬件环境决定的,它与算法无关。所以,我们可假设执行每条语句所需的时间均为单位时间。此时对算法的运行时间的讨论就可转化为讨论该算法中所有语句的执行次数,即频度之和了。
例如:两个n阶矩阵做乘法,程序如下并写出每一条语句的执行次数:
for(i=1;i<=n;i++) //n+1次
for(j=1;j<=n;j++){ //n(n+1)次
c[i][j]=0; //n*n次
for(k=0;k<=n;k++) //n*n*(n+1)次
c[i][j]=c[i][j]+a[i][k]*b[k][j]; //n*n*n次
}
第(1)句:i从1到n为n次,第n+1次不符合循环条件退出循环;
第(2)句:第1句执行n次,同理每次执行该行语句n+1次;
第(3)句:第1句,第2句各有效执行n次;
第(4)句:第1句,第2句各有效执行n次,循环体执行n+1次;
第(5)句:三层循环各有效执行n次;
总的时间消耗为:
当n趋于无穷大时,T(n)与n^3同阶,引入大O记号:,这就是求解矩阵乘法问题的算法的渐进时间复杂度。—般情况下,不必计算所有操作的执行次数,而只考虑算法中基本语句执行的次数,它是问题规模n的某个函数,用T(n)表示。
对基本语句的理解:
(1)算法中重复执行次数和算法的执行时间成正比的语句;
(2)对算法运行时间的贡献最大;
(3)重复次数最多;
对问题规模的理解:
排序: n为记录数
矩阵: n为矩阵的阶数
多项式:n为多项式的项数
集合:n为元素个数
树: n为树的结点个数
图: n为图的顶点数或边数
3.分析算法时间复杂度的方法
(1)找出语句频度最大的那条语句作为基本语句;
(2)计算基本语句的频度得到问题规模n的某个函数f(n);
(3)取其数量级用符号“O”表示;
例1:
可知:时间复杂度是由嵌套最深层的语句的频度所决定的。
例2(写成级数求和):
例3:(对数级)
注意:有的情况下:算法中基本操作重复次数随问题的输入数据集不同而不同。(需要考虑最坏和最好情况)
最坏时间复杂度:指在最坏情况下,算法的时间复杂度。
平均时闻复杂度:指在所有可能输入实例在等概率出现的情况下,算法的期望运行时间。
最好时间复杂度:指在最好情况下,算法的时间复杂度。
一般总是考虑在最坏情况下的时间复杂度,以保证算法的运行时间不会比它更长。
对于复杂算法,可以分解成几部分容易求的部分,然后利用加法规则或者乘法规则:
时间复杂度按数量级递增的顺序为:
4.渐近空间复杂度简介
空间复杂度:算法所需存储空间的度量,记作;
其中n为问题的规模(或大小)。
算法要占据的空间分两部分:(1)算法本身要占据的空间,输入/输出,指令,常数,变量等;(2)算法要使用的辅助空间;
例:逆序存放数组