程序性能分析

算法分析

计算机算法是指解决问题的步骤,应该具有可执行性,确定性,有穷性三个特点。
设计一个“好的”算法,应该达到的目标是健壮的, 无二义性的

ps:健壮的是指当输入出现非法错误时,算法会进行合适的处理,而不是产生难以理解的输出结果

算法分析的方法有解析方法实验测量方法,从解析的角度又分为时间复杂度分析和空间复杂度分析。

程序性能

空间复杂度

空间复杂度是指程序运行所需的内存大小

程序员对空间复杂度感兴趣的原因:
①在任何一个计算机上运行程序,需要保证有足够的内存能用
②不同的解决方案对内存可能有不同的要求,一般希望选择更优的方案,把更多的内存留作他用
③通过对空间复杂度的分析,可以对问题的规模进行一个大致的估计

时间复杂度

时间复杂度是指程序运行所需要的时间
一个程序的时间复杂度取决与问题的规模(n)待处理数据的初态
程序员对时间复杂度感兴趣的原因:
①为避免过长的等待而造成损失,根据具体问题会对程序有一个运行时间上限的要求
②与用户进行交互的程序需要一个令人满意的实时响应
③同样的,对于不同的解决方案一般选择更优的方案

空间复杂度

程序所需空间组成

指令空间(instruction space)

编译之后程序指令所需的空间
大小和编译器有关,相同编译器对相同程序的编译结果也可能不同

数据空间(data space)

所有常量和变量所需要的存储空间,分两部分
常量和简单变量
动态数组和动态类实例等动态对象(复杂的变量, composite variables)

环境栈空间(environment stack space)

函数被调用的时候,函数的返回地址(端断口地址)当前函数的所有局部变量和形式参数都被保存到环境栈中

空间复杂度分析

上面说的是一个程序运行所需要的空间
和特征实例相关的部分
在这里插入图片描述
只包括复杂变量的数据空间和递归函数的环境栈空间
因此,一个程序运行所需要的空间大致可以分为固定部分可变部分,其中可变部分主要依赖于实例特征(feature of instance):
S( p ) = Sp(feature) + constant

时间复杂度

①找到算法的基本语句(执行次数最多的语句),通常是最内层循环体
②计算基本语句执行次数的数量级(以最高次的为主)
③用渐进记号表示时间复杂度

ps:语句的执行次数成为语句频度或者执行频度,记为T(n)

渐进记法(approximate notations)

1.O记法

f(n) = O(g(n))表示函数f(n)的增长不会快于(渐近小于等于)函数g(n)
习惯上g(n)是满足上式的最小单位项(系数为1),例如O(3n2+6n+9) = O(n2),其中"="读作“是”

2.Ω记法

f(n) = Ω(g(n))表示函数f(n)的增长不会慢于(渐近大于等于)函数g(n)

3.θ记法

f(n) = θ(g(n))表示函数f(n)的增长渐近等于函数g(n)

时间复杂度分析

时间复杂度分析是一种事前分析估算的方法

常见的时间复杂度

由小到大:
O(1) < O(lg n) < O(n) < O(nlg n) < O(n2) < O(n3) < … <O(2n) < O(n!)
Best Case:
Worst Case:
Average Case:

常见算法的时间复杂度分析

渐近时间复杂度的分析方法

计步法
代入法

例1:
在这里插入图片描述
观察问题规模的特点,我们不妨假设2k < n ≦ 2k+1,因此有2k-1 < n/2 ≦ 2k
n = 1时成立
设当n < n0时都成立,则有T(n) ≦ cn ⌈ \lceil log2n ⌉ \rceil
将T( ⌊ n / 2 ⌋ \lfloor n/2 \rfloor n/2) 和 T( ⌈ n / 2 ⌉ \lceil n/2 \rceil n/2)带入
T(n) ≤ \leq cn×k + cn/2 ≤ \leq cn×k + cn = cn ⌈ l o g   2   n ⌉ \lceil log~2~n \rceil log 2 n

例2:
在这里插入图片描述
根据递推式我们可以得出T(n)的渐近时间为O(n2),因此我们可以据此作出假设,令T(n) ≤ \leq c1n2 - c2n,c1,c2为待定常数,随后的证明就简单了

递归树

1.极端情况:T(n) = T(0) + T(n - 1) + cn
做渐近分析时,将递推式展开,T(n) = nT(0) + c[1 + 2 + … + (n - 1) + n] = O(n2)
递归树如下所示:树的深度h = n
在这里插入图片描述
2.一般情况:T(n) = T(αn) + T(βn) + θ(n)
这样问题的时间复杂度一般是O(nlg n)
在递归树的表示中很容易看出,这里也可以计算得到
左边子树的最大深度为 log1/αn,右边子树的最大深度为 log1/βn
因此T(n)的渐近值 cnlog1/αn ≤ \leq T(n) ≤ \leq cnlog1/βn
下图以T(n) = T(0.1n) + T(0.9n) + θ(n)为例:
在这里插入图片描述

Master Method

分治算法中常要用到递归方法来处理其中的问题
分支策略三步走:分解, 解决,合并
主方法表现形式:
T(n) = aT(n/b) + f(n) , a > 1, b > 1
n:问题规模
a:子问题数量
n/b:子问题规模
①若存在ε满足,f(n) = O( n l o g b a − ε n^{log_{b}a-ε} nlogbaε),则T(n) = θ( n l o g b a n^{log_{b}a} nlogba)
②若f(n) = O( n l o g b a n^{log_{b}a} nlogba),则T(n) = θ( n l o g b a l g n n^{log_{b}a} lgn nlogbalgn)
③若存在ε满足,f(n) = O( n l o g b a + ε n^{log_{b}a+ε} nlogba+ε),则T(n) = θ(f(n))
例:
①对于递推式T(n) = 9T(n/3) + n
则有a = 9, b = 3, f(n) = n
当ε = 1时,有 n l o g b a − ε n^{log_{b}a-ε} nlogbaε = n l o g 3 9 − 1 n^{log_{3}9-1} nlog391 = n = f(n)
因此,T(n) = θ( n 2 n^2 n2)
②对于递推式T(n) = T(2n/3) + 1
则有a = 1, b = 2/3, f(n) = 1
f(n) = O( n l o g b a n^{log_{b}a} nlogba) = O(1)
因此, T(n) = θ(lgn)
③对于递推式T(n) = 3T(n/4) + nlg n
T(n) = O(nlg n)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值