本篇博客包括:
- 算法
- 算法设计的原则
- 算法效率的度量方法和准则
- 算法的存储空间需求
##算法
###概念
是对特定问题求解步骤的一种描述,是有限指令集。
###特性
(1)有穷性:算法经有限步骤后结束
(2)确定性:每一步必须是明确的
(3)可行性:每一步都是可行的
(4)输入
(5)输出
###算法的描述
算法的描述
(1)自然语言
(2)专用工具
(3)程序设计语言
(1)就是分析一下。
(2)就是流程图、ER图、时序图、xml图、各种图以及伪代码等等。
(3)就是C或者Java或者其他。
##算法设计的原则
设计算法时,通常应考虑达到以下目标:
- 可读性
- 正确性
- 健壮性
- 高效率以及低存储
这个找对象的原则差不多。
- 好看
- 确定是男的/女的
- 健壮/身材好
- 你懂
##算法效率的度量方法和准则
通常有两种度量算法效率的方法:
- 事后统计法
缺点:
1、必须执行程序
2、其它因素掩盖算法本质 - 事前分析估算法
和算法执行时间相关的因素:
1、算法选用的策略
2、问题的规模
3、编写程序的语言
4、编译程序产生的机器代码的质量
5、机器执行指令的速度
###如何估算算法的时间复杂度?
算法的执行时间:
所有语句执行时间的总和=语句的执行次数*执行一次需要的时间
则有:
设:每条语句执行一次需要的时间为单位时间
则:算法的执行时间= 该算法中所有语句频度之和
语句频度:一条语句重复执行的次数
###时间复杂度
设算法中所有语句的语句频度之和为t(n)
f(n)是当n趋向无穷大时与t(n)的同阶无穷大
则算法的时间复杂度T (n) = O(f(n))
其中:
n为算法的运算规模
f(n)是运算时间随n增大时的增长率
O(f(n))是算法时间特性的量度
时间复杂度:
从算法中选取一种对于所研究的问题来说是 基本语句 的原操作,以该基本语句 在算法中重复执行的次数作为算法运行时间的衡量准则。
基本语句:算法中重复执行次数和算法的执行时间成正比的语句。
例子:
void Mult(int a[], int b[], int& c[] ) {
// 以二维数组存储矩阵元素,c 为 a 和 b 的乘积
for (i=1; i<=n; ++i)
for (j=1; j<=n; ++j) {
c[i,j] = 0;
for (k=1; k<=n; ++k)
c[i,j] += a[i,k]*b[k,j];
}
}
其中,基本操作为:c[i,j] += a[i,k]*b[k,j];即乘法操作。
时间复杂度为O(n^3)。
例子:
++x;
基本运算:++x;即x增加1。
基本运算的执行频度:1
时间复杂度:T(n)=O( 1 )
例子:
for (i=1 ;i<=n;++i)
++x;
基本运算:同上。
基本运算的执行频度:n
时间复杂度:T(n)=O( n )
例子:
for ( i=2 ;i<=n;++i)
for (j=2 ;j<=i-1;++j)
++x;
基本运算:同上同上上。
基本运算的执行频度:
(n-1)(n-2)/2
解:
- 1)、
i=2时,执行次数=0;
i=3时,执行次数=1;
i=4时,执行次数=2;
。。。。。。
i=n时,执行次数=n-2; - 2)、
执行频度=0+1+2+3+。。。。。。+n-4+n-3+n-2。
因为:
1+n-2=n-1;
2+n-3=n-1;
3+n-4=n-1;
。。。。。。
所以: - 3)、
当n为偶数时:
频度f(n)=((n-2)/2)(n-1)=(n-1)(n-2)/2。
当n为奇数时:
频度f(n)=((n-2)+1)/2+(((n-2)-1)/2)(n-1)。
化简,得:f(n)=(n-1)(n-2)/2。
因此,频度f(n)=(n-1)(n-2)/2。
解法(没念过高中的给我gun):
则,时间复杂度T(n)=O(f(n))。
f(n)化简为:
f(n)=n^2-3n+2
则,T(n)=O(n^2-3n+2)。
时间复杂度,研究最坏情况下,所以取最高次幂。
即,T(n)=O(n^2)。
###算法时间复杂度和算法运行时间关系
###时间复杂度相关结论
(1)通常认为具有指数阶量级的算法是实际不可计算的,而量级低于平方阶的算法是高效的。
(2)随着n值的增大,增长速度各不相同,n足够大时,存在下列关系:
对数函数<幂函数<指数函数
(3)算法的时间复杂度还与数据的初始状态等因素有关。
##算法的存储空间需求
算法存储量包括:
- 输入数据所占空间
- 程序本身大小
- 辅助变量所占空间
现在硬件过剩的年代,基本不考虑程序本身所占大小了。剩下的还是要考虑的,例如在Android编程中,需要考虑到String和StringBuffer的区别,来达到内存占用最小化,等等。