演算法複雜度詳解

2021-08-19 18:46:36 字數 3292 閱讀 7304

一、定義

一般情況下,演算法中 基本操作重複執行的次數是問題規模n的某個函式,用t(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大時,t(n)/f(n)的極限值為不等 於零的常數,則稱f(n)是t(n)的同數量級函式。記作t(n)=o(f(n)),稱o(f(n))為演算法的漸進時間複雜度(o是數量級的符號 ),簡稱時間複雜度。

(1)時間頻度 

乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道演算法花費的時間多少(魔鏡魔鏡告訴我,那個演算法是跑得快的演算法0.0)

乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就多。

乙個演算法中的語句執行次數稱為語句頻度或時間頻度。記為t(n)。

(2)時間複雜度 

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)) 為演算法的漸進時間複雜度,簡稱時間複雜度。

注意,時間頻度與時間複雜度是不同的,時間頻度不同但時間複雜度可能相同。

如:t(n)=n^2+3n+4與t(n)=4n2+2n+1它們的頻度不同,但時間複雜度相同,都為o(n^2)。

常見的時間複雜度有:

常數階o(1)《對數階o(log2n)《線性階o(n),《線性對數階o(nlog2n)

《平方階o(n^2)《方階o(n3)

《指數階o(2^n)

(3)最壞時間複雜度和平均 時間複雜度  最壞情況下的時間複雜度稱最壞時間複雜度。一般不特別說明,討論的時間複雜度均是最壞情況下的時間複雜度。 這樣做的原因是:最壞情況下的時間複雜度是演算法在任何輸入例項上執行時間的上界,這就保證了演算法的執行時間不會比任何更長。

在最壞情況下的時間複雜度為t(n)=0(n),它表示對於任何輸入例項,該演算法的執行時間不可能大於0(n)。 平均時間複雜度是指所有可能的輸入例項均以等概率出現的情況下,演算法的期望執行時間。

指數階0(2n),顯然,時間複雜度為指數階0(2n)的演算法效率極低,當n值稍大時就無法應用。

2、最壞時間複雜度和平均時間複雜度

對於時間複雜度的分析,一般是這兩種方法:

(1)最壞時間複雜度

最壞情況執行時間

通常,除非特別指定,我們提到的執行時間都是最壞情況的執行時間

對於追問為什麼是最壞時間複雜度的好奇寶寶:

1、如果最差情況下的複雜度符合我們的要求,我們就可以保證所有的情況下都不會有問題。(完美=w=)

2、也許你覺得平均情況下的複雜度更吸引你(見下),但是:第一,難計算第二,有很多演算法的平均情況和最差情況的複雜度是一樣的. 第三,而且輸入資料的分布函式很可能是你沒法知道。

(2)平均時間複雜度

平均時間複雜度也是從概率的角度看,更能反映大多數情況下演算法的表現。當然,實際中不可能將所有可能的輸入都執行一遍,因此平均情況通常指的是一種數學期望值,而計算數學期望值則需要對輸入的分布情況進行假設。平均執行時間很難通過分析得到,一般都是通過執行一定數量的實驗資料後估算出來的。

二、求時間複雜度

1、根據定義,可以歸納出基本的計算步驟 

(1.)計算出基本操作的執行次數t(n) 

基本操作即演算法中的每條語句的執行次數一般預設為考慮最壞的情況。

(2)計算出t(n)的數量級 

求t(n)的數量級,只要將t(n)進行如下一些操作:

忽略常量、低次冪和最高次冪的係數

令f(n)=t(n)的數量級。

(3)用大o來表示時間複雜度 

例:for(i=1;i<=n;++i)

}則有 t(n)= n^2+n^3,根據上面括號裡的同數量級,我們可以確定 n^3為t(n)的同數量級

則有f(n)= n^3,然後根據t(n)/f(n)求極限可得到常數c

則該演算法的 時間複雜度:t(n)=o(n^3)

2、於是我們發現根本沒必要都算,所以我們有了精簡後的步驟:

1. 找到執行次數最多的語句 

2. 計算語句執行次數的數量級

3. 用大o來表示結果 

eg:(1)   for(i=1;i<=n;i++)     //迴圈了n*n次,當然是o(n^2)

for(j=1;j<=n;j++)

s++;

(2)for(i=1;i<=n;i++)   //迴圈了(n+n-1+...+1)≈(n^2)/2 ,同上                                              

for(j=i;j<=n;j++)

s++;

(4)   i=1;k=0;

while(i<=n-1)

//迴圈了

//n-1≈n次,所以是o(n)

(5)   for(i=1;i<=n;i++)

for(j=1;j<=i;j++)

for(k=1;k<=j;k++)

x=x+1;

//迴圈了(1^2+2^2+3^2+...+n^2)=n(n+1)(2n+1)/6≈(n^3)/3,

//即o(n^3)

(6)x=91; y=100;

while(y>0) if(x>100) else x++;

//t(n)=o(1),與n無關

(7)i=n-1;            

while(i>=0&&(a[i]!=k))       

i--;        

return i;   

//此演算法中的語句(3)的頻度不僅與問題規模n有關,還與輸入例項中a的各元素取值及k的取值有關: ①若a中沒有與k相等的元素,則語句(3)的頻度f(n)=n; ②若a的最後乙個元素等於k,則語句(3)的頻度f(n)是常數0。

綜上:

1、取決於執行次數最多的語句,如當有若干個迴圈語句時,演算法的時間複雜度是由巢狀層數最多的迴圈語句中最內層語句的頻度f(n)決定的。

2、如果演算法的執行時間不隨著問題規模n的增加而增長,即使演算法中有上千條語句,其執行時間也不過是乙個較大的常數。此類演算法的時間複雜度是o(1)

3、演算法的時間複雜度不僅僅依賴於問題的規模,還與輸入例項的初始狀態有關。

演算法複雜度O nlogn 詳解

首先看以下程式段 for int i 1 i n i for int j 1 j n j i 複雜度為o 1 求該程式段的時間複雜度。可以看出 1 當i 1時,需要執行n次 2 當i 2時,需要執行n 2次 3 當i 3時,需要執行n 3次 4 當i n 1時,需要執行n n 1次 5 當i n時,...

2演算法複雜度詳解

1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就...

演算法的時間複雜度和空間複雜度詳解

演算法的時間複雜度和空間複雜度合稱為演算法的複雜度。1.時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算...