一、算法的设计目标
1、正确性:满足具体问题的解,基本目标。
2、可读性:有利于人去理解算法。
3、健壮性:输入非法数据,能适当做出处理,不产生莫名其妙的输出。
4、高效性:包括时间的高效性和空间的高效性。
二、算法性能指标
1、算法的时间效率也称为时间复杂度。
算法的时间复杂度反映了算法执行的时间长短。度量一个算法在计算机上执行的时间通常有两种方式:
(1)、事后统计法
(2)、事前分析法:(常用)
编写算法使用的高级语言 编程产生的机器语言代码质量 机器指令执行速度 问题规模O()函数:表示算法的时间效率与算法所处理的数据元素个数n函数关系的最常用函数是O()函数。
定义: 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得
当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n))
为算法的渐进时间复杂度,简称时间复杂度。当算法的时间复杂度T(n)与问题规模n无关时,此时算法的时间复杂度T(n)=O(1)。
例如:计算下列算式的前N项和 1-2+3-4+5.....+N
分析:当N为奇数时,和为:(N+1)/2 当N为偶数时,和为:-N/2
栗子1:
//设数组a和b在前面部分已经赋值,求如下两个n阶矩阵相乘算法的时间复杂度 for(i=0;i<n;i++) { for(j=0;j<n;j++) { c[i][j]=0; //基本语句1 for(k=0;k<n;k++) { c[i][j]=c[i][j]+a[i][k]*b[k][j];//基本语句2 } } }
分析:f(n)=c1*n2+c2*n3 ,所以T(n)=O(n3)栗子2:
//设n为如下算法处理的数据元素个数,求算法时间复杂度。 for(i=1;i<=n;i=i*2) { System.out.println(i); }
分析:执行次数为2f(n)<=n; f(n)<=log2n 所以T(n)=O(log2n)
2、算法的空间效率也称为空间复杂度。
空间复杂度是指算法在运行期间所需要的内存空间的数量级。
由于大部分算法的空间复杂度问题并不严重,并且算法的空间复杂度分析方法和算法的时间复杂度分析方法基本相同,所以一般数据结构只讨论算法的时间复杂度,不讨论算法的空间复杂度。
栗子1:
//分析如下算法的空间复杂度 static void reserse(int[] a,int[] b) { int n= a.length; for(int i=0;i<n;i++) { b[i]=a[n-1-i]; } }
分析:当程序调用reserse(a,b)函数时,要分配的内存空间包括:引用a,引用b,局部变量n和局部变量i;因此f(n)=c;其中c为
常量。所以该算法的空间复杂度S(n)=O(1)
说明:
同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率。算法分析的目的在于选择合适算法和改进
算法。一个算法的评价主要从时间复杂度和空间复杂度来考虑。算法时间的高效性和空间的高效性通常是矛盾的。所有一般只
会取一个平衡点。通常我们假设程序运行在内存中,且内存容量足够使用,所以更多的讨论时间复杂度。
三、小结
算法的时间复杂度和两个因素有关:算法中的最大嵌套循环层数;最大嵌套循环结构中每次循环的次数。
一般来说,具有多项式时间复杂度的算法是可以接受的,具有指数时间复杂度的算法,只有当n足够小时才可以使用。一般效率较好的算法要控制在O(N)或者O(log2 N)