目录
前言
程序 = 数据结构+算法
数据结构通过算法实现操作
算法根据数据结构设计程序
一、算法
定义:对特定问题求解方法和步骤的一种描述,它是指令的有限序列。其中,每个指令表示一个或多个操作。
简而言之,算法就是解决问题的方法和步骤。
1.1 算法与程序
- 算法
算法是解决问题的一种方法或过程,考虑如何将输入转换成输出,一个问题可以有多种算法 - 程序
程序是用某种程序设计语言对算法的具体实现
1.2 算法描述方法
- 自然语言:中文、英语等
- 流程图:传统流程图、NS流程图(盒图)等
- 伪代码:类C语言(类语言)等
- 程序代码:C语言程序、JAVA语言程序等
1.3 算法特性
- 有穷性
一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成 - 确定性
在任何条件下,只有唯一的一条执行路径,即对于相同的输入只能得到相同的输出 - 可行性
算法是可执行的,算法描述的操作可以通过已经实现的基本操作执行有限次来实现 - 输入
一个算法有零个或多个输入 - 输出
一个算法有一个或多个输出
1.4 算法设计的要求
- 正确性(Correctness)
如果一个算法以一组满足初始条件的输入开始,那么该算法的执行一定会终止,并且在终止时得到满足要求的输出 - 可读性(Readability)
一个算法的描述应该是便于人的阅读,以便于人对算法的理解 - 健壮性(Robustness)
算法的健壮性也叫鲁棒性,指当输入不合法的数据时,算法恰当地作出反应。
处理出错的方法,不应是中断程序的执行,而是应该返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理。 - 高效性(Efficiency)
要求花费尽量少的运行时间和存储空间
二、算法分析
一个好的算法首先要具备正确性,然后是健壮性,可读性,在几个方面都满足的情况下,主要考虑算法的效率,通过算法的效率高低来评判对同一个问题的不同算法的优劣程度。
算法效率包含时间效率和空间效率
时间效率:指的是算法执行完成后所耗费的时间
空间效率:指的是算法执行过程中所耗费的存储空间
有时候,算法的时间效率和空间效率两者之间会出现矛盾,不能既要时间效率,又要空间效率。所以,有些情况需要用时间效率换空间效率,还有些情况需要用空间效率换时间效率。
下面,分别介绍如何分析一个算法的时间效率和空间效率
2.1 算法时间效率的度量
度量算法的时间效率的方法包含以下两种:
- 事后统计
事后统计是指将算法使用程序设计语言实现后运行,统计其时间和空间的开销 - 事前分析
事前分析是指对算法所消耗的资源按照某种方法进行估算
由于事后统计这个度量方法需要编写程序实现算法,所得统计结果依赖于计算机的软硬件等环境因素,掩盖算法本身的优劣。所以,采用事前分析这个度量方法进行算法时间效率的分析。
2.1.1 事前分析方法
一个算法的运行时间是指一个算法在计算机上运行所耗费的时间大致可以等于计算机执行一种简单操作所需的时间与算法中进行简单操作次数的乘积
算法运行时间 = ∑每条语句的执行次数×该语句执行一次所需的时间
语句的执行次数又称为语句频度
每条语句执行一次所需时间,一般随机器而异。取决于机器的指令性能、速度以及编译的代码质量。是由机器本身软硬件环境决定的,与算法无关。
所以,假设执行每条语句所需的时间均为单位时间。那么对算法的运行时间的讨论就可以转化为讨论该算法中所有语句的执行次数,即频度之和。通过这样,就可忽略机器的软硬件环境。
根据以上,可得出算法运行时间 = ∑每条语句的频度
例子,两个n×n矩阵相乘的算法可描述为(类C语言描述):
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][i]; //n*n*n次
}
算法所耗费的时间定义为该算法每条语句频度之和,则上述算法的时间消耗为:
T ( n ) = n + 1 + n ∗ ( n + 1 ) + n ∗ n + n ∗ n ∗ ( n + 1 ) + n ∗ n ∗ n T(n) = n+1+n * (n+1)+n * n+n * n * (n+1)+n * n * n T(n)=n+1+n∗(n+1)+n∗n+n∗n∗(n+1)+n∗n∗n
整理得 T ( n ) = 2 n 3 + 3 n 2 + 2 n + 1 T(n) = 2n^3 +3n^2+2n+1 T(n)=2n3+3n2+2n+1
为了便于比较不同算法的时间效率,这里仅仅比较不同算法的数量级,即算法的渐进时间复杂度
算法的渐进时间复杂度
若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数,即
T ( n ) = O ( f ( n ) ) T(n)=O(f(n)) T(n)=O(f(n))
称 O ( f ( n ) ) O(f(n)) O(f(n))为算法的渐进时间复杂度( O O O是数量级的符号),简称时间复杂度。
那么,根据算法的渐进时间复杂度的定义,对于求解矩阵相乘问题,算法耗费时间:
T ( n ) = 2 n 3 + 3 n 2 + 2 n + 1 T(n)=2n^3+3n^2+2n+1 T(n)=2n3+3n2+2n+1
n → ∞ {n \to \infty} n→∞时, T ( n ) / n 3 → 2 {T(n)/n^3 \to 2} T(n)/n3→2,那么, T ( n ) 和 n 3 T(n)和n^3 T(n)和n3是同阶或同数量级,引入大 O O O记号,则 T ( n ) T(n) T(n)可记作:
T ( n ) = O ( n 3 ) T(n)=O(n^3) T(n)=O