什麼是時間複雜度

2021-10-02 15:48:34 字數 3904 閱讀 9046

演算法的時間複雜度,是乙個用於度量乙個演算法的運算時間的乙個描述,本質是乙個函式,根據這個函式能在不用具體的測試資料來測試的情況下,粗略地估計演算法的執行效率,換句話講時間複雜度表示的只是**執行時間隨資料規模增長的變化趨勢。

常用大o來表述,這個函式描述了演算法執行所要時間的增長速度,記作f(n)。演算法需要執行的運算次數(用函式表示)記作t(n)。存在常數 c 和函式 f(n),使得當 n >= c 時 t(n) <= f(n),記作 t(n) = o(f(n)),其中,n代表資料規模也就是輸入的資料。常見排序複雜度如圖:

大o表示法

大o符號,又叫做道朗符號,是數學中用另乙個較為簡單的函式去描述函式漸進行為的乙個符號,用來刻畫被截斷的無窮級數尤其是漸近級數的剩餘項。

常見複雜度量級

分類記作

常量階o(1)

對數階o(logn)

線性階o(n)

線性對數階

o(nlogn)

n方階o(nⁿ)

指數階o(2ⁿ)

階乘階o(n!)

常量階:只要**的執行時間不隨 n 的增大而增長,這樣**的時間複雜度都記作 o(1)。或者說,一般情況下,只要演算法中不存在迴圈語句、遞迴語句,即使有成千上萬行的**,其時間複雜度也是ο(1)。

對數階:

i=1;

while

(i <= n)

分析上段**,i的取值是乙個首項為1,公差為2的等比數列:

2º·2¹·2²·2³····2ⁿⁿ = n,其中nn即為項數,求對數即 nn=log₂n。時間複雜度為o(log₂n)。

線性階、n方階:一般情況下,如果迴圈體內迴圈控制變數為線性增長,那麼包含該迴圈的演算法的時間複雜度為o(n),線性階巢狀線性階的演算法時間複雜度為o(nⁿ),涉及下文乘法法則。

線性對數階:當乙個線性階**段法巢狀乙個對數階**段,該演算法的時間複雜度為o(nlogn)

指數階和階乘階:根據函式,隨著n的增加,執行時間會無限急劇增加,因此效率非常低下。

最大階法則:忽略式子中的常量,低階,係數,只計算最大階的量級。

說白了就只關注迴圈次數最多的**段。

int

fun(

int n)

for(

; i <= n;

++i)

}return sum;

}

**本身沒有意義,只是為了舉例,上述**的時間複雜度為o(n²)。

加法法則:總複雜度等於量級最大**段的複雜度,公式:

t(n)=t1(n)+t2(n)=max(o(f(n)), o(g(n))) =o(max(f(n), g(n)))

int

fun(

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;

}

三段**的複雜度分別是o(1)、o(n)、o(n²),根據法則:t(n)=t1(n)+t2(n)=max(o(f(n)), o(g(n))) =o(max(f(n), g(n)))。即為o(n²)。

乘法法則:巢狀**複雜度等於巢狀內外**複雜度之積。公式:

t(n)=t1(n)*t2(n)=o(f(n))*o(g(n))=o(f(n)*g(n))。

int

fun1

(int n)

}int

fun2

(int n)

return sum;

}

fun1方法中,忽略掉fun2()的呼叫複雜度為o(n)。fun2方法的時間複雜度是o(n),根據法則,t(n) = t1(n) * t2(n) = o(n*n) = o(n²)。

其中比較特殊的一種不符合上述3個法則:

int

fun(

int m,

int n)

int sum_2 =0;

int j =1;

for(

; j < n;

++j)

return sum_1 + sum_2;

}

當前複雜度有兩種資料規模 m 和 n 確定,加法法則應更正為:t1(m) + t2(n) = o(f(m) + g(n)),即時間複雜度為o(m+n)。

最好時間複雜度:在最理想的情況下,執行這段**的時間複雜度。

最壞時間複雜度:在最糟糕的情況下,執行這段**的時間複雜度。

平均時間複雜度:考慮各種情況及其發生的概率,得到的時間複雜度。

均攤時間複雜度:均攤時間複雜度是一種特殊的平均複雜度,把耗時多的複雜度均攤到耗時低的複雜度,得到的時間複雜度。

快速排序最好時間複雜度計算

快速排序最優的情況就是每一次取到的元素都剛好平分整個陣列。 此時的時間複雜度公式則為:

t[n] = 2t[n/2] + f(n);

t[n/2]為平分後的子陣列的時間複雜度,f[n] 為平分這個陣列時所花的時間;下面來推算下,在最優的情況下快速排序時間複雜度的計算(用迭代法):

** t[n] = 2t[n/2] + n ——————————————— 第一次遞迴,令:n = n

t[n] = 2 + n ———————————第二次遞迴,令:n = n/2= = 2^2 t[ n/ (2^2) ] + 2n

t[n] = 2^2 + 2n ———————第三次遞迴 ,令:n = n/(2^2)= 2^3 t[ n/ (2^3) ] + 3n

t[n] = 2^m t[1] + mn ———————————————第m次遞迴(m次後結束), 令:n = n/( 2^(m-1) )**

當最後平分的不能再平分時,也就是說把公式一直往**倒,到最後得到t[1]時,說明這個公式已經迭代完了(t[1]是常量了)。

得到:

t[n/ (2^m) ] = t[1] ===>> n = 2^m ====>> m = logn;

t[n] = 2^m t[1] + mn ;其中m = logn;

t[n] = 2^(logn) t[1] + nlogn = n t[1] + nlogn = n + nlogn ;

其中n為元素個數,又因為當n >= 2時:nlogn >= n (也就是logn > 1),所以取後面的 nlogn;

綜上所述:快速排序最優的情況下時間複雜度為:o( nlogn )

攤還分析法

通過攤還分析法得到的時間複雜度為均攤時間複雜度。

大致思路:每一次o(n)都會跟著n次o(1),所以把耗時多的複雜度均攤到耗時低的複雜度。得到的均攤時間複雜度為o(1)。

應用場景:均攤時間複雜度和攤還分析應用場景較為特殊,對乙個資料進行連續操作,大部分情況下時間複雜度都很低,只有個別情況下時間複雜度較高。而這組操作其存在前後連貫的時序關係。

這個時候我們將這一組操作放在一起分析,將高複雜度均攤到其餘低複雜度上,所以一般均攤時間複雜度就等於最好情況時間複雜度。

什麼是時間複雜度

什麼是時間複雜度 作為乙個處在學習之路的渣渣,被乙個時間複雜度的題給難倒了,然後我就思考了一下什麼是時間複雜度。雖然在學校學習了了演算法的課程,但是仔細一想,對於時間複雜度還真是不怎麼懂。於是重新學習,記下自己的一些理解。1.時間複雜度 提到時間複雜度,第一時間想到的是演算法,簡單說,演算法就是你解...

什麼是時間複雜度

什麼是時間複雜度 作為乙個處在學習之路的渣渣,被乙個時間複雜度的題給難倒了,然後我就思考了一下什麼是時間複雜度。雖然在學校學習了了演算法的課程,但是仔細一想,對於時間複雜度還真是不怎麼懂。於是重新學習,記下自己的一些理解。1.時間複雜度 提到時間複雜度,第一時間想到的是演算法,簡單說,演算法就是你解...

什麼是時間複雜度和空間複雜度

先簡要介紹一下 演算法複雜度分為時間複雜度和空間複雜度。其作用 時間複雜度是指執行這個演算法所需要的計算工作量 而空間複雜度是指執行這個演算法所需要的記憶體空間。時間和空間 即暫存器 都是計算機資源的重要體現,而演算法的複雜性就是體現在執行該演算法時的計算機所需的資源多少。時間複雜度 1 演算法的時...