時間複雜度的計算方法

2021-06-26 07:43:45 字數 4159 閱讀 5411

1.1 頻度統計法。

頻度統計法指以程式中語句執行次數的多少作為演算法時間度量分析的一種方法。通常情況下,演算法的時間效率主要取決於程式中包含的語句條數和採用的控制結構這兩者的綜合效果。因此,最原始且最牢靠的方法是求出所有主要語句的頻度f(n),然後求所有頻度之和。

例如:如下形式的語句段:

for (i=1;i

這個由兩個for語句構成的程式段,外迴圈的重複執行次數是n-1次,內迴圈的單趟重複執行次數是2×n次。因此,語句y++的頻度為n-1,語句x++的頻度為2×n×(n-1)。

所以, t(n)=o(∑f(n))=o(n-1+2×n2-2×n)

取增長最快的一項作為數量級,則 t(n)=o(n2)

該方法簡單,結果絕對精確,適用於大多數程式。但分析演算法時間效率時往往只需計算出其大致數量級,此時,採用頻度估算法即可。

1.2 頻度估算法。

先找出對於所求解的問題來說是共同的原操作,並求出原操作的語句頻度f(n),然後直接以f(n)衡量t(n)。在使用頻度估算法時應注意到乙個顯著的標誌,就是原操作往往是最內層迴圈的迴圈體,並且,完成該操作所需的時間與運算元的具體取值無關。這種方法比較適合於帶有多重迴圈的程式。

例如:數學中求兩個矩陣乘法的常規方法是用了乙個三重迴圈,如下:

for (i=1;i<=n;i++)

} 這個程式段的原操作是處於最內層迴圈的語句c[i][j]=c[i][j]+a[i][k]*b[k][j],該語句的重複執行次數即原操作的頻度是n3,可以直接得出:該演算法的時間複雜度t(n)=o(n3)。

對於一些複雜的演算法,可以將演算法分解成容易估算的幾個部分,利用頻度估算法分別求出這幾部分的時間複雜度,然後利用求和的原則得到整個演算法的時間複雜度。

頻度估算法的優點是結果較精確,方法簡單且易掌握,但對於原操作的頻度不易直接確定的程式,卻無能為力。

1.3 頻度未知數法。

當不能直接求出原操作的重複執行次數f(n),但通過對程式主要語句的分析,確信可以通過間接的方式計算得出。其基本規律是:首先將原操作的頻度設為乙個未知數,然後根據原操作執行結束的條件及特徵列方程求出它,如果結果是不等式,取其極大值。

比如程式段: i=s=0;

while (s

分析:該程式段的原操作是語句s+=i,無法一眼看出原操作的頻度f(n)。為求得f(n),設迴圈體共執行了k次後結束,即令f(n)=k,則根據語義,可以得出

1+2+3+……+k>=n 且 1+2+3+……+(k-1)

由以上兩式,可得方程組

取其極值,並忽略常數對數量級的影響,可得 t(n)=o( )=o( )

1.4 列舉頻度歸納法。

程式中經常會出現帶有倍增型迴圈的情況。倍增迴圈指內迴圈的執行次數隨外迴圈控制變數而變化的多重迴圈結構。

例如: m=1;

for (i=1;i<=n;i++)

分析:當外迴圈變數i分別從1,2,……,一直取到n時,內迴圈的執行次數依次是2,4,8,……,2n,這是乙個幾何級數序列,其中每一項的值是前一項的常數倍。

因此,這種演算法的特徵是,原操作的頻度和乙個變化的量有關,比如內迴圈的執行次數依賴於外迴圈的迴圈控制變數,或每執行一次迴圈,迴圈控制變數將被乘以(除以)乙個常數。

再如: for (i=0;i

for (j=i;j

for (k=j;k

x++;

分析:由於最內層for迴圈控制語句執行1次,其迴圈體即原操作x++恰好執行了n-j次,因此,整個演算法完成時共執行了 次x++語句,而

結論:當分析帶有倍增迴圈結構程式的執行時間開銷時,需要把每次執行迴圈的時間累加起來,其結果表示式往往就被轉化為乙個級數求和的問題。

1.5 頻度期望值法。

當原操作的執行次數不僅依賴於問題的規模,而且隨原始資料集狀態的不同而不同時,往往需要根據原始資料的分布特點,考慮資料在某種概率分布下頻度的乙個平均值。此時,即使問題規模相同,對於不同的特定輸入,其時間開銷也不同。

在這種情形下,考慮求符合某種概率分布情況下的原操作的平均頻度,然後以平均頻度的乙個數量級作為演算法的時間度量。

例如:順序查詢演算法

int search_seq(table s,keytype key)

// table是查詢表型別,keytype表示關鍵字型別

分析:該演算法中的原操作是「將記錄的關鍵字和給定值進行比較」,但根據 for迴圈的判斷條件,比較的次數取決於待查記錄在查詢表中的位置i。根據所查詢資料在查詢表中位置的不同,其時間開銷可能在乙個很大的範圍內浮動。為求出時間複雜度,通常轉而求「其關鍵字和給定值進行過比較的記錄的個數的平均值」,即「比較次數」的平均頻度。一般來說,在進行研究時,為方便討論,對於經典的查詢和排序演算法,總是考慮「等概率」條件。

所以,各記錄的查詢概率依次為:

第i個記錄的比較次數 是: =n-i+1

故,平均頻度

所以,t(n)= =o(n)

根據原始資料集的分布特點,有些查詢問題的檢索概率不一定相等,但求解的方法相同,都是求某種概率分布下的乙個期望值。對於原操作的執行次數依賴於原始資料排列情況的問題來說,內迴圈體的執行次數取決於外迴圈控制變數的情形非常常見,其求解方法也完全適用。例如:大多數靜態的排序演算法。

需要說明的一點是:資料分布的特點對於很多查詢演算法效率都會有很大的影響,而平均情況分析並不總是可行。因為,首先要求了解清楚資料是如何分布的。對於這一類問題,有時候要根據各種可能出現的最壞情況來估算演算法的時間複雜度。

1.6 遞迴演算法時間複雜度的計算技巧。

遞迴過程的執行時間一般都能通過乙個遞迴關係式得到很好的體現。根據對遞迴關係式的不同計算方法,將遞迴演算法的求解方法提煉為如下兩種。

1.6.1擴充套件遞迴迭代法。

當需要找到乙個遞迴問題的精確答案時,可採用一種遞迴擴充套件技術。其基本方法是:方程右邊較小的項根據定義被依次替代,如此反覆擴充套件,直到得到乙個沒有遞迴式的完整數列,從而將複雜的遞迴問題轉化為了新的求和問題。

例如: float fact(long int n)

分析:遞迴函式fact每遞迴呼叫自身一次,問題規模就減少1。該函式中出口語句的執行時間為o(1);呼叫返回的結果與輸入引數相乘,這個操作的執行時間是乙個常量可以記為o(1)。因此,函式fact的時間代價就等於該常數加上執行遞迴呼叫的時間,可以表示成

c n<=1

t(n)= c為遞迴呼叫語句的執行時間,這裡是常數o(1) 則,

=……所以,函式fact的時間複雜度是o(n)。

利用遞迴本身的特點採用這種擴充套件技術求解遞迴程式的時間效率,是一種保守且可靠的方法。但有些問題,其求和序列的推導可能會是一項比較繁瑣而枯燥的純數學工作。遇到這種情況時,完全可以讓個人的經驗充分發揮作用,利用經驗去猜測答案。

1.6.2上下限猜測法。

先試著猜測答案,找出乙個認為是正確的上下限估計,然後再去證明它。如果歸納證明成功,那麼再試著收縮上下限;如果證明失敗,那麼就放鬆限制重試;一旦上下限符合要求,就得到了所求的答案。

例如:以下方程描述歸併排序的執行時間,其數學的推導方法非常繁瑣,現用上下限猜測技術來估算其漸進時間複雜度。

1 n=2

t(n)=

不失一般性,先猜測這個遞迴有乙個上限 o(n2),更準確地說,假定t(n)≤n2,通過歸納來證明這個假定是否正確。如果正確,繼續收縮上限,猜測乙個更小的估計。

為了使計算簡便,假定n是2的乘方。初始情況:t(2)=1≤22,顯然成立。

假設當i≤n時 t(i)≤i2 成立,要證明對於所有的n=2n,n≥1,t(n) ≤n2能夠得到t(2n) ≤(2n)2。

而 t(2n)=2t(n)+2n≤2n2+2n≤4n2≤(2n)2 至此命題得證。

所以,猜測t(n)≤o(n2)是正確的。

但是o(n2)可能是乙個很高的估計。如果猜測更小一些,例如t(n)≤cn(c為某個常數),很明顯,因為c2n=2cn,沒有為額外的代價n留下餘地,使待排序的兩塊歸併在一起,因此t(n)≤cn不可能成立。這樣就可以初步得知,真正的代價一定在cn與n2之間。

繼續嘗試t(n)≤nlog2n。初始情況: t(2)=1≤(2•log22)=2。歸納假設t(n)≤nlog2n,那麼:t(2n)=2t(n)+2n≤2nlog2n+2n≤2n(log2n+1) ≤2nlog22n

類似地,還可以證明t(n)≥(nlog2n)。所以,t(n)就是o(nlog2n)。

在求解漸近時間複雜度時,這種猜測技術是一種很有用的技術,當尋找精確解時,就不適用了。

2. 結束語

提倡在解決問題時,首先要詳細分析演算法的特性及特徵,然後再按照不同的特性採用合適的方法區別對待,具體問題具體分析,從而避免不必要的代價和周折,達到快速而準確求解的目的。

時間複雜度計算方法

o 1 constant complexity constant 常數複雜度 o log n 對數複雜度 o n 線性時間複雜度 o n 2 平方 o n 3 立方 o 2 n 指數 o n 階乘 隨著現在儲存空間的便宜,很多情況下,我們是願意用空間複雜度來換取時間複雜度的,因為記憶體,磁碟等這些和...

時間複雜度計算方法

o 1 constant complexity constant 常數複雜度 o log n 對數複雜度 o n 線性時間複雜度 o n 2 平方 o n 3 立方 o 2 n 指數 o n 階乘 隨著現在儲存空間的便宜,很多情況下,我們是願意用空間複雜度來換取時間複雜度的,因為記憶體,磁碟等這些和...

時間複雜度計算方法

1.形如 t n a t n b f n 的時間複雜度計算方法 有一種方法叫做主方法 master method 是用來專門計算這種形式的時間複雜度的,方法具體如下 下邊舉例進行說明 例1 t n 25 t n 5 n 2 因為 a 25,b 5,d 2,f n n 2 所以此例符合master m...