幾種常見的時間複雜度例項分析
o(1)
o(logn)
o(m+n),o(m*n)
資料結構和演算法本身解決的是快和省的問題
衡量執行效率的就需要時間空間複雜度分析
複雜度分析是整個演算法學習的精髓,只有掌握了他,資料結構和演算法的內容就基本掌握了一半。
1)測試結果依賴測試環境
2)測試結果受資料規模的影響很大
所以結合上述兩種情況,就需要乙個不用具體的測試資料來測試,就可以粗略的估算演算法的執行效率的方法。也就是時間空間複雜度。
從cpu的角度來看,每一行**的操作都是讀資料-運算-寫資料
即,可以把一行**的時間看作乙個 unit_time時間單位
如下例子1
public
class
helloworld
public
static
intcal
(int n)
return sum;
}}
上述時間單位綜合為 1+1+n+n
即(2n+2)* unit_time
由此,所有**的執行時間t(n)與每行**的執行次數成正比
依照上述思路 看下個
例子2
public
static
intcal
(int n)
}return sum;
}
所以以上的總時間就是1+1+1+n+n+n2+n2 = 3+2n+2n2
即總共的耗時是3+2n+2n2個時間單位。
以上可以得出 所有**的執行時間t(n)與每行**的執行次數成正比。
總結公式就是
t(n)= o(f(n))
t(n) :**執行所需要的時間
f (n):表示每行**執行的次數總和。
o表示**執行時間和次數總和是成正比的。即需要時間越長,執行的次數越多。
例子1 2n+2
例子2 3+2n+2n2
公式化:t(n) = o(2n+2)
公式化:t(n) = o(3+2n+2n2)
以上就是大o表示法了,大o表示法表示的是 **執行時間隨資料規模增長的變化趨勢
在公式中低階,常量,係數三部分並不左右增長趨勢。只需要記錄乙個最大量級就可以了。
公式化:t(n) = o(2n+2)
公式化:t(n) = o(3+2n+2n2)
以上公式化內容寫成以下即可
t(n) = o(n);
t(n) = o(n2);
大o表示法,表示的是趨勢,同時會省略掉公式中的常量,低階,係數,並且只需要記錄最大量級。
分析乙個演算法,**就是只關注迴圈次數最多的**那一段**就可以了。這一段最多的執行次數的量級就是這段**的時間複雜度
例子1
public
static
intcal
(int n)
return sum;
}
以上例子執行次數最多的就是for迴圈,與n的大小無關。for迴圈執行了n次,所以這段**的時間複雜度就是o(n);
例子1
public
static
intcal
(int n)
int sum_2 =0;
int q =1;
for(
; q < n;
++q)
int sum_3 =0;
int i =1;
int j =1;
for(
; i <= n;
++i)
}return sum_1 + sum_2 + sum_3;
}
以上**分為三個部分
sum_1 部分 sum_2部分 sum_3部分
sum_1 迴圈執行100次常量級 t(n) = o(n);
sum_2 迴圈執行n次常量級 t(n) = o(n);
sum_3 迴圈執行n2次指數級 t(n) = o(n2);
取出最大量級,所以例子1的時間複雜度就是o(n2);
抽象成公式:
t1(n) = o(f(n)) , t2(n) = o(g(n)) 兩個**執行時間 等於整個方法的執行時間
t(n) = t1(n) + t2(n)
但是取最大的時間作為時間複雜度
即t(n) = max(o(f(n)),o(g(n)))
若假設t1(n) = o(n),t2(n) = o(n2) 則 t1(n) * t2(n) = o(n3)
在**中的體現就是巢狀迴圈
例子1
public
static
intcal
(int n)
return ret;
}private
static
intf
(int n)
return sum;
}
上述**在迴圈中呼叫f方法 f方法的本身的時間複雜度是o(n)
cal如果不看f方法,時間複雜度也是o(n) 但是在cal中呼叫了f
所以整個cal方法的時間複雜度就是tcal(n) *tf(n) = o(n2)
複雜度量級
公式常量級
o(1)
對數級o(logn)
線性級o(n)
線性對數級
o(nlogn)
平方階o(n2)
立方階o(n3)
k次方階
o(nk)
指數階o(2n)
階乘階o(n!)
以上只有指數階,階乘階,是非多項式量級
其餘的都是多項式量級
時間複雜度是非多項式量級叫做np問題。
因為隨著n的規模增加,執行時間會急劇增加,執行時間會無限增長。
一般情況下,只要演算法中不存在迴圈語句,遞迴語句,即便成千上萬行**,時間複雜度都是o(1)常量階
例子1
public
static
intcal
(int n)
return i;
}
以上**迴圈次數最多的是while
i = 2 +2平方 + 2立方 + …2x
求x = log2n
即上述時間複雜度就是o(logn)
這種時間複雜度與上述的不同,他的**的複雜度,是由兩個資料的規模來決定的
例子1
public
static
intcal
(int m,
int n)
int sum_2 =0;
int j =1;
for(
; i < n;
++i)
return sum_1 + sum_2;
}
例子中傳入m和n兩個資料規模,沒有辦法評估誰大誰小。
所以上述**的時間複雜度就是o(m+n)
針對上述情況,原來的加法法則不正確,公式改為o(f(m)+g(n)).
從 低 到 高
o(1),o(logn),o(n),o(nlogn),o(n2)。
複雜度分析 時間複雜度 空間複雜度
執行效率是演算法的乙個重要的考量指標,演算法的執行效率用時間 空間複雜度來衡量。今天我們來學習一下複雜度的分析。通常我們可以通過執行程式來獲得演算法的真正的執行時間,這種方法我們可以稱為事後統計法,但這種方法得到的是具體的資料,測試結果很依賴測試環境,而且受資料規模影像最大。因此,我們需要乙個不需要...
複雜度分析 時間複雜度分析和空間複雜度分析
其實,只要講到資料結構與演算法,就一定離不開時間 空間複雜度分析。而且我個人認為,複雜度分析是整個演算法學習的精髓,只要掌握了它,資料結構和演算法的內容基本上就掌握了一半。1.時間複雜度分析 對於剛才羅列的複雜度量級,我們可以粗略地分為兩類,多項式量級和非多項式量級。其中,非多項式量級只有兩個 o ...
複雜度分析(上)時間複雜度 空間複雜度
為了肉眼 實時 快速地來分析出 的複雜度,我們需要乙個不用具體的測試資料來測試,就可以粗略地估計演算法的執行效率的方法。時間複雜度 空間複雜度 表示演算法的執行時間與資料規模之間的增長關係。每行 對應的 cpu 執行的個數 執行的時間都不一樣,但是,我們這裡只是粗略估計,所以可以假設每行 執行的時間...