演算法複雜度分為時間複雜度和空間複雜度。
其作用:
時間複雜度是指執行演算法所需要的計算工作量;
而空間複雜度是指執行這個演算法所需要的記憶體空間。
(演算法的複雜性體現在執行該演算法時的計算機所需資源的多少上,計算機資源最重要的是時間和空間(即暫存器)資源,因此複雜度分為時間和空間複雜度)。
簡單來說,時間複雜度指的是語句執行次數,空間複雜度指的是演算法所佔的儲存空間
時間複雜度
計算時間複雜度的方法:
用常數1代替執行時間中的所有加法常數
修改後的執行次數函式中,只保留最高階項
去除最高階項的係數
按數量級遞增排列,常見的時間複雜度有:
常數階O(1),對數階O(log2n),線性階O(n),
線性對數階O(nlog2n),平方階O(n^2),立方階O(n^3),…,
k次方階O(n^k),指數階O(2^n)。
隨著問題規模n的不斷增大,上述時間複雜度不斷增大,演算法的執行效率越低。
舉個栗子:
sum = n*(n+1)/2; //時間複雜度O(1)
for(int i = 0; i < n; i++){
printf("%d ",i);
}
//時間複雜度O(n)
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ",i);
}
}
//時間複雜度O(n^2)
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
printf("%d ",i);
}
}
//執行次數為(1+n)*n/2
//時間複雜度O(n^2)
int i = 0, n = 100;
while(i < n){
i = i * 2;
}
//設執行次數為x. 2^x = n 即x = log2n
//時間複雜度O(log2n)
最壞時間複雜度和平均時間複雜度
最壞情況下的時間複雜度稱最壞時間複雜度。一般不特別說明,討論的時間複雜度均是最壞情況下的時間複雜度。
這樣做的原因是:最壞情況下的時間複雜度是演算法在任何輸入例項上執行時間的上界,這就保證了演算法的執行時間不會比任何更長。
平均時間複雜度是指所有可能的輸入例項均以等概率出現的情況下,演算法的期望執行時間。設每種情況的出現的概率為pi,平均時間複雜度則為sum(pi*f(n))
常用排序演算法的時間複雜度
演算法 | 最差時間分析 | 平均時間複雜度 | 穩定度 | 空間複雜度 |
---|---|---|---|---|
氣泡排序 | O(n2) | O(n2) | 穩定 | O(1) |
快速排序 | O(n2) | O(n*log2n) | 不穩定 | O(log2n)~O(n) |
選擇排序 | O(n2) | O(n2) | 穩定 | O(1) |
二叉樹排序 | O(n2) | O(n*log2n) | 不穩定 | O(n) |
插入排序 | O(n2) | O(n2) | 穩定 | O(1) |
堆排序 | O(n*log2n) | O(n*log2n) | 不穩定 | O(1) |
希爾排序 | O | O | 不穩定 | O(1) |
空間複雜度
空間複雜度(Space Complexity)是對一個演算法在執行過程中臨時佔用儲存空間大小的量度,記做S(n)=O(f(n))。
對於一個演算法來說,空間複雜度和時間複雜度往往是相互影響的。當追求一個較好的時間複雜度時,可能會使空間複雜度的效能變差,即可能導致佔用較多的儲存空間;反之,當追求一個較好的空間複雜度時,可能會使時間複雜度的效能變差,即可能導致佔用較長的執行時間。
有時我們可以用空間來換取時間以達到目的。