時間頻度
乙個演算法執行所耗費的時間。
從理論上講時間是不能計算出來的,必須上機執行測試才能知道,但我們不可能也沒有必要對每個演算法都上機執行測試,我們只需要知道哪個演算法花費的時間多,哪個演算法花費的時間少即可。並且乙個演算法花費的時間與演算法中語句的執行次數成正比,所以乙個演算法中語句執行的次數多,它花費時間就多。
乙個演算法中的語句執行次數稱為語句頻度或時間頻度,記為t(n)。
時間複雜度
在時間頻度中,n稱為問題的規模。當n不斷變化時,時間頻度t(n)也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。
一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用t(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大時,t(n)/f(n)的極限值為不等於零的常數,則稱f(n)是t(n)的同數量級函式。記作t(n)=o(f(n)),稱o(f(n)) 為演算法的漸進時間複雜度,簡稱時間複雜度。
求解演算法時間複雜度的具體步驟
⑴ 找出演算法中的基本語句
演算法中執行次數最多的那條語句就是基本語句,通常是最內層迴圈的迴圈體。
⑵ 計算基本語句的執行次數的數量級
只需計算基本語句執行次數的數量級,這就意味著只要保證基本語句執行次數的函式中的最高次冪正確即可,可以忽略所有低次冪和最高次冪的係數。這樣能夠簡化演算法分析,並且使注意力集中在最重要的一點上:增長率。
⑶ 用大ο記號表示演算法的時間效能
將基本語句執行次數的數量級放入大ο記號中。
補充:
如果演算法中包含巢狀的迴圈,則基本語句通常是最內層的迴圈體,如果演算法中包含並列的迴圈,則將並列迴圈的時間複雜度相加。例如:
for
(i=1
; i<=n; i++
) x++
;for
(i=1
; i<=n; i++
)for
(j=1
; j<=n; j++
) x++
;
第乙個for迴圈的時間複雜度為ο(n),第二個for迴圈的時間複雜度為ο(n2),則整個演算法的時間複雜度為ο(n+n2)=ο(n2)。
ο(1)表示基本語句的執行次數是乙個常數,一般來說,只要演算法中不存在迴圈語句,其時間複雜度就是ο(1)。其中ο(log2n)、ο(n)、ο(nlog2n)、ο(n2)和ο(n3)稱為多項式時間,而ο(2n)和ο(n!)稱為指數時間。計算機科學家普遍認為前者(即多項式時間複雜度的演算法)是有效演算法,把這類問題稱為p(polynomial,多項式)類問題,而把後者(即指數時間複雜度的演算法)稱為np(non-deterministic polynomial, 非確定多項式)問題。
在計算演算法時間複雜度時有幾個簡單的程式分析法則
(1)對於一些簡單的輸入輸出語句或賦值語句,近似認為需要o(1)時間
(2)對於順序結構,需要依次執行一系列語句所用的時間可採用大o下"求和法則"
求和法則:是指若演算法的2個部分時間複雜度分別為 t1(n)=o(f(n))和 t2(n)=o(g(n)),則 t1(n)+t2(n)=o(max(f(n), g(n)))
特別地,若t1(m)=o(f(m)), t2(n)=o(g(n)),則 t1(m)+t2(n)=o(f(m) + g(n))
(3)對於選擇結構,如if語句,它的主要時間耗費是在執行then字句或else字句所用的時間,需注意的是檢驗條件也需要o(1)時間
(4)對於迴圈結構,迴圈語句的執行時間主要體現在多次迭代中執行迴圈體以及檢驗迴圈條件的時間耗費,一般可用大o下"乘法法則"
乘法法則: 是指若演算法的2個部分時間複雜度分別為 t1(n)=o(f(n))和 t2(n)=o(g(n)),則 t1*t2=o(f(n)*g(n))
(5)對於複雜的演算法,可以將它分成幾個容易估算的部分,然後利用求和法則和乘法法則技術整個演算法的時間複雜度
另外還有以下2個運算法則:(1) 若g(n)=o(f(n)),則o(f(n))+ o(g(n))= o(f(n));(2) o(cf(n)) = o(f(n)),其中c是乙個正常數
o(1)
int a=2;
int b=2;
int c=
2;
以上三條單個語句的頻度均為1,該程式段的執行時間是乙個與問題規模n無關的常數。演算法的時間複雜度為常數階,記作t(n)=o(1)。注意:如果演算法的執行時間不隨著問題規模n的增加而增長,即使演算法中有上千條語句,其執行時間也不過是乙個較大的常數。此類演算法的時間複雜度是o(1)。
o(n)
int i, n =
100, sum =0;
for( i=
0; i < n; i++
)/執行n+
1次/
這段**的時間複雜度為o(n),因為迴圈體中的**需要執行n次。
o(n2)
int i, j, n =
100;
for( i=
0; i < n; i++
)/執行n+
1次/}
根據以上**,n=100,也就是說外層迴圈每執行一次,內層迴圈就執行100次,那麼程式要執行完兩個迴圈,需要執行100*100次,也就是n的平方,所以這段**的時間複雜度為o(n2)。
在這個例子中,迴圈條件i從0到99,每次都要讓j迴圈100次,如果非常較真的研究總共精確執行次數,那是非常累的。另一方面,我們研究演算法的複雜度,側重的是研究演算法隨著輸入規模擴大增長量的乙個抽象,而不是精確地定位需要執行多少次,因為如果這樣的話,我們就又得考慮回編譯器優化等問題,然後,然後就永遠也沒有然後了!
那麼問題就來了,要是有三個這樣的巢狀迴圈,時間複雜度就是n3。
注意
int i, j, n =
100;
for( i=
0; i < n; i++
)}
根據以上**分析,當i=0時,內迴圈執行了n次;當i=1時,內迴圈則執行n-1次……當i=n-1時,內迴圈執行1次,所以總的執行次數是:n+(n-1)+(n-2)+…+1 = n(n+1)/2
。用我們推導大o的攻略,第一條忽略,因為沒有常數相加。第二條只保留最高項,所以n/2這項去掉。第三條,去除與最高項相乘的常數,最終得時間複雜度為o(n2)。
o(log2n)
int i =
1, n =
100;
while
( i < n )
由於每次i*2之後,就距離n更近一步,假設有m個2相乘後大於或等於n,則會退出迴圈。於是由2^m = n大約得到m = log2n,所以這個迴圈的時間複雜度為o(log2n)。 dfs時間複雜度 時間複雜度 空間複雜度
時間複雜度的數學證明方法相對比較複雜,通常在工程實際中,會分析就好。注意 只看最高複雜度的運算 int for for for for int遞迴如何分析時間複雜度?常數係數可以忽略,在分析時不用考慮,只要說以上術語即可。主定理 master throrem 上述第四種是歸併排序,所有排序演算法,最...
時間複雜度 空間複雜度
時間複雜度 在電腦科學中,演算法的時間複雜度是乙個函式,它定性描述了該演算法的執行時間。這是乙個關於代表演算法輸入值的字串 的長度的函式。時間複雜度常用大o符號 表述,不包括這個函式的低階項和首項係數。計算時間複雜度的方法 1 只保留高階項,低階項直接丟棄 2 係數不要 3 執行次數是常數是為o 1...
時間複雜度 空間複雜度
演算法複雜度分為時間複雜度和空間複雜度。其作用 時間複雜度是指執行演算法所需要的計算工作量 而空間複雜度是指執行這個演算法所需要的記憶體空間。一 時間複雜度 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道...