演算法的時間複雜度反映了程式執行時間隨輸入規模增長而增長的量級,在很大程度上能很好反映出演算法的優劣與否。演算法執行時間需通過依據該演算法編制的程式在計算機上執行時所消耗的時間來度量。而度量乙個程式的執行時間通常有兩種方法。
t (n) = ο(f (n)) 表示存在乙個常數c,使得在當n趨於正無窮時總有 t (n) ≤ c * f(n)。例如,o(2n2+n +1) = o (3n2+n+3) = o (7n2 + n) = o ( n2 ) 。注意到大o符號裡隱藏著乙個常數c,所以f(n)裡一般不加係數。特殊的,當演算法中語句執行次數為乙個常數時,時間複雜度為o(1)。
另外,在時間頻度不相同時,時間複雜度有可能相同,如t(n)=n2+3n+4與t(n)=4n2+2n+1它們的頻度不同,但時間複雜度相同,都為o(n2)。
按數量級遞增排列,常見的時間複雜度有:
隨著問題規模n的不斷增大,上述時間複雜度不斷增大,演算法的執行效率越低。
從圖中可見,我們應該盡可能選用多項式階o(nk)的演算法,而不希望用指數階的演算法。
常見的演算法時間複雜度由小到大依次為:ο(1)<ο(log2n)<ο(n)<ο(nlog2n)<ο(n2)<ο(n3)<…<ο(2n)<ο(n!)
具體步驟是:
找出演算法中的基本語句,演算法中執行次數最多的那條語句就是基本語句,通常是最內層迴圈的迴圈體。
計算基本語句的執行次數的數量級,只需計算基本語句執行次數的數量級,這就意味著只要保證基本語句執行次數的函式中的最高次冪正確即可,可以忽略所有低次冪和最高次冪的係數。這樣能夠簡化演算法分析,並且使注意力集中在最重要的一點上:增長率。
用大ο記號表示演算法的時間效能,將基本語句執行次數的數量級放入大ο記號中。
如果演算法中包含巢狀的迴圈,則基本語句通常是最內層的迴圈體,如果演算法中包含並列的迴圈,則將並列迴圈的時間複雜度相加。
例如:
for (i = 1; i <= n; i++)第乙個for迴圈的時間複雜度為ο(n),第二個for迴圈的時間複雜度為ο(n2),則整個演算法的時間複雜度為ο(n+n2)=ο(n2)。x++;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
x++;
對於一些簡單的輸入輸出語句或賦值語句,近似認為需要o(1)時間
對於順序結構,需要依次執行一系列語句所用的時間可採用大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)) 。
對於選擇結構,如if語句,它的主要時間耗費是在執行then字句或else字句所用的時間,需注意的是檢驗條件也需要o(1)時間 。
對於迴圈結構,迴圈語句的執行時間主要體現在多次迭代中執行迴圈體以及檢驗迴圈條件的時間耗費,一般可用大o下"乘法法則",乘法法則: 是指若演算法的2個部分時間複雜度分別為 t1(n)=o(f(n))和 t2(n)=o(g(n)),則 t1*t2=o(f(n)*g(n)) 。
對於複雜的演算法,可以將它分成幾個容易估算的部分,然後利用求和法則和乘法法則技術整個演算法的時間複雜度
另外還有以下2個運算法則
temp =i;以上三條單個語句的頻度均為1,該程式段的執行時間是乙個與問題規模n無關的常數。演算法的時間複雜度為常數階,記作t(n)=o(1)。注意:如果演算法的執行時間不隨著問題規模n的增加而增長,即使演算法中有上千條語句,其執行時間也不過是乙個較大的常數。此類演算法的時間複雜度是o(1)。i =j;
j = temp;
2.1. 交換i和j的內容
sum = 0; //因為θ(2n2+n+1)=n2(即:去低階項,去掉常數項,去掉高階項的常參得到),所以t(n)= =o(n2);(一次)
for (i = 1; i <= n; i++) //
(n + 1次)
for (j = 1; j <= n; j++) //
(n2次)
sum++; //
(n2次)
2.2.
for (i = 1; i < n; i++)語句1的頻度是n-1,語句2的頻度是(n-1)*(2n+1)=2n2-n-1,f(n)=2n2-n-1+(n-1)=2n2-2;又(2n2-2)=n2,該程式的時間複雜度t(n)=o(n2)。
一般情況下,對步進迴圈語句只需考慮迴圈體中語句的執行次數,忽略該語句中步長加1、終值判別、控制轉移等成分,當有若干個迴圈語句時,演算法的時間複雜度是由巢狀層數最多的迴圈語句中最內層語句的頻度f(n)決定的。
a = 0t(n)=2+n+3(n-1)=4n-1=o(n).;b = 1; //
1for (i = 1; i <= n; i++) //
2
i = 1; //取最大值f(n)=log2n,t(n)=o(log2n )1while (i <=n)
i = i * 2; //
2
for (i = 0; i < n; i++)當i=m, j=k的時候,內層迴圈的次數為k當i=m時, j 可以取 0,1,...,m-1 , 所以這裡最內迴圈共進行了0+1+...+m-1=(m-1)m/2次所以,i從0取到n, 則迴圈共進行了: 0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6所以時間複雜度為o(n3).}
演算法複雜度 時間複雜度和空間複雜度
1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數...
演算法複雜度 時間複雜度和空間複雜度
演算法複雜度 時間複雜度和空間複雜度 關鍵字 演算法複雜度 時間複雜度 空間複雜度 1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時 間多,哪個演算法花費的時間少就可以...
演算法複雜度 時間複雜度和空間複雜度
演算法的時間複雜度是指執行演算法所需要的計算工作量。n稱為問題的規模,當n不斷變化時,時間頻度t n 也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用t n 表示,若有某個輔助函式f n 存在乙個正...