比较合并排序法与插入排序法,一旦输入n的规模足够大时,合并排序在最坏情况所需的时间Θ,而插入排序法在最坏情况所需的时间为Θ,当n足够大时,合并排序法的效率远远超过插入排序法。对於足够大的输入,一个演算法所需的时间受到最高次项的影响要远远超过低次项与常数项,因此,在输入够大的情况会将其忽略。
当输入够大时,演算法所需的时间只和增加的量级有关,我们通常只关心演算法的渐进效率(asymptotic efficiency)。所谓渐进效率,即是当输入的数量够多时,演算法所需的时间和输入的数量呈现怎样的关系,是呈现线性关系,还是指数关系等等。
用来描述演算法渐进运行时间的渐进式符号是以一个定义域为自然数集合 = { }的函数来定义。而这样定义函数的定义域有助於我们在处理最坏的情况,当然,我们也可以按照渐进符号的使用情况,让这些符号的定义域在任意集合,如实数域等等集合。
前面我们写到插入排序法的最差情况为Θ,使用Θ这个渐进符号来描述演算法所需要的时间。而Θ这样的表示法,是由我们推导出来的所写出来的,其中这些皆为常数,通过写成,渐进符号通常应用在函数或是多项式上。
渐进式分析是基於以下几个观点
所谓的渐进式符号,为描述演算法趋势的一个函数集合。
给定一个函数,使用Θ来表示以下函数的集合:
Θ = { 存在正实数和使得对所有,有}
如果存在正整数,使得对於足够大的n,能够被和之间,我们就可以说是属於Θ这个函数集合中。
我们具体的证明Θ这个式子,令属於正整数集合,使得对所有,有
,把除掉,得到
得到选择任意,可以使得对於任意的值成立,而对於,可以使对於任意成立。因此,当且,可以证明Θ。当然,对於其他一些常数也是如此,重点是存在某一个常数,可以被包含在Θ这个函数集合中。
简单来说,一个式子忽略掉常数和低阶项,举例:Θ(注意: θ是大写),他所表示的概念是大於等於并且小於等於。
一般情况,会以Θ描述这样的观念,这里的'='不是'等於'的意思,而是'属於'的意思
在上图我们可以看到函数和将函数夹在中间。看到图形的x轴,我们可以看到当往n的方向逼近,的值是高於但低於的,换句话说,对所有,函数必然在n到的范围中,找到一个k使得,这时候我们会称是的一个渐进临界线(asymptotically tight bound)。
如果存在一个正实数c和使得当时,则表示为,通常用於评估一个演算法最久要花费多少时间,也就是一个演算法的上限,小於等於的概念,一个演算法至少会小於等於Big-O函数集合的概念。
另外一个集合的观点,我们可以发现Θ这个观念中,其实蕴含这个概念。
Example 1 : ,小於或是等於,根据上面的定义,我们不能说等於,我们只能说是属於的子集。因此这里的等号需要理解成属於某个集合的概念,更精确的写法,也可以写∈ 。
Example 2 : ,表示存在一个函数 ∈使得
Example 3 : ,对所有函数∈ ,存在∈ ,使得
如果存在一个正实数c和使得当时 ,则表示为 Ω,表是一个演算法的下界,也就是最好的情况,花最少时间的时候,大於等於的概念,一个演算法至少会大於等於Ω。
Example 1 : √ = Ω 概念上为当n足够大时,√总是大於等於Ω
我们上面介绍到Big-O这个渐进符号,但是我们可以发现到Big-O所提供的渐进情况可能不是精确的,像是,这个使用Big-O的确是精确的上界,但是,虽然是函数的上界,但却不是精确的。我们这里使用little-o来表示一个非渐进式的精确上界。
Example 1 : ,但是
比较Big-O和little-o之间的差别,Big-O为,而little-o为,两者主要差别在,也就是函数的增长率是小於还是严格小於的差别,因此little-o是比Big-O还要来得强烈的叙述,little-o是比较小的函数集合。
ΘΘ蕴含Θ
蕴含
ΩΩ蕴含Ω
蕴含
ωω蕴含ω
Θ类似於
类似於
Ω类似於
类似於
ω类似於
以上这一些定义目的在於为两个函数之间提供一个可以相对比较的标的或是准则,给定两个函数,通常函数上会存在一些点,在这一些点上函数值小於另一个函数的值或是大於函数得值,因此,像这样的表示事实上是不具有任何意义的。
於是,我们比较他们的相对递增率(relative rate of growth),当我们将这个概念应用到演算法效率分析时,我们所进行的比较就能够体现出意义了。
而上面这些用来描述一个演算法执行时间的函式,我们称为该演算法的时间复杂度,如果使用Big-O对进行描述,会称一个演算法的时间复杂度为
参考资料: Introduciton to algorithms 3rd
<button onClick={this.deleteRow.bind(this, 'id'...
程序架构 昨天只有介绍到Arduino的程序架构可以分为两大函式: setup()及loop()。 ...
昨天认识了Python三种运算子中,分别是算术运算子、比较运算子以及逻辑运算子,你还记得分别是哪些吗...
现在开发者写程序,最方便的一点,就是不会的地方,可以问 Google 在 Google 中输入 Sw...
软件开发中,产品经理在规划产品方案时,都会注意用户体验的部分,其实关於用户体验的部分 James G...