1. 程式人生 > >資料結構與演算法分析-演算法分析 Algorithm Analysis

資料結構與演算法分析-演算法分析 Algorithm Analysis

一.數學基礎

     定義1:如果存在正常數cn_{0}使得當N\gen_{0}時T(N)\lecf(N),則記為T(N) = O(f(N))

     定義2:如果存在正常數cn_{0}使得當N\gen_{0}時T(N)\gecg(N),則記為T(N) = \Omega(g(N))

     定義3:T(N) = \Theta(h(N))當且僅當T(N) = O(h(N))和T(N) = \Omega(g(N))

     定義4:如果對每一正常數c都存在常數n_{0}使得當N>n_{0}時T(N)<cp(N),則T(N) = o(p(N)),也就是說T(N) = O(p(N))且T(N)\ne\Theta(p(N)),則T(N) = o(p(N))

     這些定義的目的在於可以比較函式的相對增長率(Relative Rate of Growth),換句話講:

       數學表示式                                   相對增長率
T(N) = O(f(N))   T(N)的增長率\leF(N)增長率
T(N) = \Omega(g(N))   T(N)的增長率\geF(N)增長率
T(N) = \Theta(h(N))   T(N)的增長率=F(N)增長率
T(N) = o(p(N))

  T(N)的增長率<F(N)增長率

        當T(N) = O(f(N))時,f(N)是T(N)的一個上界(upper bound),當T(N) = \Omega(g(N))是,f(N)是T(N)的一個下界(lower bound)。看函式增長變化率有以下幾個法則:

      法則1:若T_1(N) = O(f(N))且T_2(N) = O(g(N)),那麼(a).T_1(N)+T_2(N)=O(f(N)+g(N)),(b)T_1(N)\times T_2(N)=O(f(N)\times g(N))

      法則2:若T(N)是一個k次多項式,則T(N) =  \Theta (N^{k})

      法則3:對任意常數k,\log ^{k}N = O(N)

      我們在運算的時候一般不把常數和低次項放入括號中,在大O的任何分析中,要求的精度比較低

      我們能通過計算{\lim_{N \to +\infty}}f(N)/g(N)來確定兩個函式的相對增長率,必要時可以使用洛必達法則。若極限為0,則f(N) = o(g(N));若極限為c\ne0,意味著f(N) = \Theta(g(N));若極限是{\infty},則g(N) = o(f(N));若極限擺動,則兩者無關。

二.執行時間計算

      要分析的最重要的資源就是執行時間,一般我們定義兩個函式,一個為平均執行時間,一個為最壞情況執行時間。為了簡化分析,我們做出如下約定:不存在特定的執行時間單位,拋棄前導的常數與低階項,大O的運演算法則如下:

      法則1:for迴圈的執行時間為執行一次的時間乘上迭代次數

      法則2:for迴圈的巢狀,若有N個for迴圈巢狀,演算法複雜懂就為O(N^{k})

      法則3:順序語句將各個語句執行時間求和即可

      法則4:分支判斷語句if/else總時間不超過if執行時間加上else執行時間

三.執行時間的對數  

      分析演算法最混亂的方面在對數的分析上,某些分治演算法將以O(N{log}N)時間執行,對數最常出現的規律可概括為:

      如果一個演算法用常數時間O(1)將問題的大小削減為其一部分(通常為1/2),那麼該演算法就為O(logN)。另一方面,如果使用常數時間只是把問題減少一個常數的數量,那麼這種演算法就是O(N)的。