【背景】
在概述(二)中,我们着重介绍了对
【标准记号与常用函数】
单调函数
单调递增:
单调递减:
严格单调递增:
严格单调递减:
取整函数
向下取整:
向上取整:
取整函数若干性质
-
对于
有:
多项式函数
指数函数
对于正整数
对数函数
对所有实数
阶乘函数
Stirling's approximation:
【数列求和公式】
等差数列求和:
等比数列求和:
【非递归算法复杂性分析】
基础:
(1) for/while循环
循环体内计算时间*循环次数;
(2) 嵌套循环
循环体内计算时间*所有循环次数;
(3) 顺序语句
各语句计算时间相加;
(4) if-else语句
if语句计算时间和else语句计算时间的较大者。
一般步骤:
1. 决定用哪个(或哪些)参数作为算法问题规模的度量
可以从问题的描述中得到。
2. 找出算法中的基本语句
通常是最内层循环的循环体。
3. 检查基本语句的执行次数是否只依赖于问题规模
如果基本语句的执行次数还依赖于其他一些特性,则需要分别研究最好情况、最坏情况和平均情况的效率。
4. 建立基本语句执行次数的求和表达式
计算基本语句执行的次数,建立一个代表算法运行时间的求和表达式。
5. 用渐进符号表示这个求和表达式
计算基本语句执行次数的数量级,用大O符号来描述算法增长率的上限。
例子:
1 2 3 4 5 6 | int m = 0, i, j; for (i = 1; i <= n; i++){ for (j = 2*i; j <=n; j++){ m++; } } |
解法1:算法的基本操作为:
解法2:
故:
即:
【递归算法复杂性分析】
基础:
对递归算法时间复杂性的分析, 关键是根据递归过程建立递推关系式, 然后求解这个递推关系式》
例1:
1 2 3 4 | int factorial( int n){ if (n == 0) return 1; return n * factorial(n-1); } |
可得递推式:
解之:
例2:
1 2 3 4 5 6 7 8 9 | void Hanoi( int n, char A, char B, char C){ if (n == 1){ printf ( "A->C" ); } else { Hanoi(n-1, A, C, B); printf ( "A->C" ); Hanoi(n-1, B, A, C); } } |
可得递推式:
解之:
扩展递归
扩展递归(extended recusion)是一种常用的求解递推关系式的基本技术,扩展就是将递推关系式中等式右边的项根据递推式进行替换,扩展后的项被再次扩展,依次下去,会得到一个求和表达式,然后可以借助求和技术进行求解。
例:求解下述递推式时间复杂性:
解:
简单起见:设
【概述小结】
算法与程序
-
算法基本概念和性质
-
算法描述方法
问题求解过程
算法复杂性分析
-
算法复杂性基本概念
-
算法复杂性的渐近性态
-
算法渐近分析记号的定义和性质
-
非递归算法和递归算法的复杂性分析
【参考文献】
-
2019年广西师范大学计算机与信息工程学院算法设计与分析课件[OL].李志欣教授.2019.01.01
[…] 1、时间复杂度分析 20190201 20190216 20190217 […]