Data Structure 笔记20-21 (渐进分析法)

Data Structure 笔记20-21 (渐进分析法)

(作者:colinboy  Email:cybbh@163.com) 2008.6.5

(内容难免出现错误或一些专业词汇使用不当,只是个人笔记,能理解总体内容就好)

 

(笔记中, 2^n表示2n次方,其他类似)

 

设想我们有一个处理购买物品列表的算法,对于这个算法:

  -10000毫秒去读取所有的物品到内存.

  -对于每个物品,花费10毫秒的时间去处理.

 

那么要处理n个物品需要花费(10000+10n)毫秒,虽然看起来1000010大很多很多,但是当处理物品数量非常大时10n对处理时间的影响更明显.例如当n=100000,花费的时间为1010000毫秒,读取物品花费的10000毫秒对整个处理时间的影响只有1%.

 

当然,随着物品数量的增加,读取物品到内存的时间也会有所增加,但是这个时间本身就是不固定的,我们可以购买速度更快的电脑使这个时间缩短.而且使用不同的语言或者不同的编译器也会对这个时间产生影响.我们要不依赖与特定的机器以及各种环境去描述一个算法的速度,所以我们可以忽略这些常量对算法速度的影响.随着科技的发展,这些常量的影响会变的越来越小.

 

O符号(oh,不是零)

我们使用大O符号来表示随着处理数据的增长,算法花费时间的增长速度.

 

假设n是一个算法要处理的数据量,有个函数T(n),这个函数正好等于算法处理大小为n的数据所要花费的时间,现在我们设置一个更简单的函数f(n),

 

      我们说T(n)O(f(n)) 当且仅当存在一个正数常量cN对于任何n>=N都使 T(n) <= c f(n)成立.

 

例如对于函数T(n) = 10000 + 10n, 我们可以选定c为任何我们想要的数字(多大都行),f(n) = n,我们想要T(n) <= c f(n),c20, T(n)f(n)的图像如下

 

                          c f(n) = 20 n     **

           ^                /        **

           |       |       /       **

           |       |      /      **

           |       |     /     **

           |       |    /    **  T(n) = 10,000 + 10 n

   30,000  +       |   /   **

           |       |  /  **

           |       | / **

           |       |/**

   20,000  +       **

           |     **|

           |   **/ |

           | ** /  |

   10,000  **  /   |

           |  /    |

           | /     |

           |/      |

           O-------+------------------------> n

                  1000

 

T(n)f(n)相交于点(1000,20000),随着2个函数的继续增长,他们永远都不会再相交,对于N=1000,c=20,任何n>=N都可以使T(n) <= c f(n),所以我们可以说T(n) = O(f(n)).

 

 

一些推论:

 

1.          1000000n = O(n)

  证明:c=1000000,N=0.就可以满足大O的定义了.

因此,O符号一般不会考虑大多数常量(是大多数!)的影响,我们可以写1000000n = O(2n),但是这是不必要的.

 

 

2.          n = O(n^3)

证明:c=1,N=1. 就可以满足大O的定义了.

  由此可见大O符号可能会导致一些错误的观念,不能因为一个算法是O(n^3)就说明这个算法很慢(,大部分会很慢...), O符号只是表示了一个函数的增长率上限.

 

3.          n^3 + n^2 + n = O(n^3)

  O符号通常用来表示影响函数增长的主要部分,大多数情况下其他部分当n变的非常大的时候基本可以忽略.

 

 

一些重要的大O符号集合:

 

O(1)              常量

O(logN)           对数

O(log^2 N)        对数的平方

O(root(n))        平方根

O(n)              线性

O(n logN)         n倍的对数

O(n^2)            平方

O(n^3)            立方

O(n^4)            四次方

O(2^n)            指数

O(e^n)            指数,e大于2.

O(n!)             阶乘

O(n^n)            %@&@#^#$@^

 

 

对于上面的列表,上层的元素都是底层元素的子集,例如O(n^2) O(n^3).

 

 

一些重要的说明:

 

1.  n^2 = O(n),因为我们选择c=n,那么n^2 <= n^2.

错了,c必须是一个常量!

 

2.          e^3n(e3n次方) = O(e^n)因为一般都忽略常量的影响.10^n = O(2^n) 因为一般都忽略常量的影响.

很显然是错误的,只是大多数情况下可以忽略常量的影响.一个常量在一个指数的表示中就是一个特例.

 

3.          我们假设有2个算法解决一个同样的问题,第一个算法为10^8 n,第二个为10n^2,对应的大O表示第一个为O(n),第二个为O(n^2),显然O(n^2)O(n)的增长率要快很多,所以说第一个算法比第二个效率高.其实我们仔细分析,第二个算法在输入数据小于1000万时比第一个算法快,这时候大O给我们提供了错误的信息,因为第一个算法中常量的影响非常非常大,占据了算法开销的很大一部分,所以这时候忽略常量的影响就会导致一些错误结果.

 

 

 

大Ω(Omega)符号

 

Omega(f(n))是所有满足以下条件的函数T(n)的集合:存在一个常量dN,对于所有n>=N,T(n)>=d f(n).

 

大Ω和大O是相反的,如果T(n)O(f(n)),那么f(n)就是Ω(T(n)).例如:

2n是Ω(n),因为nO(2n).

n^2是Ω(n),因为nO(n^2).

n^2是Ω(3 n^2+n logn),因为3 n^2+n lognO(n^2).

 

大Ω表示了一个函数的增长率的下界, 大Ω表示一个函数增长率最慢不会慢于Ω(n).

 

 

 

大Θ(Theta)符号

 

Theta (f(n))是所有满足以下条件的函数T(n)的集合:对于T(n), T(n) = O(f(n)),T(n)= Ω(f(n)).

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值