算法的性能评价------空间复杂度和时间复杂度
生活随笔
收集整理的這篇文章主要介紹了
算法的性能评价------空间复杂度和时间复杂度
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?
一個(gè)算法的優(yōu)劣往往通過(guò)算法復(fù)雜度來(lái)衡量,算法復(fù)雜度包括時(shí)間復(fù)雜度和空間復(fù)雜度。
時(shí)間復(fù)雜度是算法的所需要消耗的時(shí)間,時(shí)間越短,算法越好。可以對(duì)算法的代碼進(jìn)行估計(jì),而得到算法的時(shí)間復(fù)雜度。
一般來(lái)說(shuō),算法代碼簡(jiǎn)短精悍可以用來(lái)減少算法的時(shí)間復(fù)雜度!
?
空間復(fù)雜度指的是算法程序在執(zhí)行時(shí)所需要的存儲(chǔ)空間。空間復(fù)雜度可以分為以下兩個(gè)方面!
1.程序的保存所需要的存儲(chǔ)空間資源。即程序的大小;
2.程序在執(zhí)行過(guò)程中所需要消耗的存儲(chǔ)空間資源,如中間變量等;
一般來(lái)說(shuō),程序的大小越小,執(zhí)行過(guò)程中消耗的資源越少,這個(gè)程序就越好!
下面為時(shí)間復(fù)雜度和空間復(fù)雜度的計(jì)算
時(shí)間復(fù)雜度是總運(yùn)算次數(shù)表達(dá)式中受n的變化影響最大的那一項(xiàng)(不含系數(shù)) 比如:一般總運(yùn)算次數(shù)表達(dá)式類似于這樣: a*2n+b*n3+c*n2+d*n*lg(n)+e*n+f a ! =0時(shí),時(shí)間復(fù)雜度就是O(2n); a=0,b<>0 =>O(n3); a,b=0,c<>0 =>O(n2)依此類推 例子: (1) for(i=1;i<=n;i++) //循環(huán)了n*n次,當(dāng)然是O(n2)for(j=1;j<=n;j++)s++; (2) for(i=1;i<=n;i++)//循環(huán)了(n+n-1+n-2+...+1)≈(n2)/2,因?yàn)闀r(shí)間復(fù)雜度是不考慮系數(shù)的,所以也是O(n2)for(j=i;j<=n;j++)s++; (3) for(i=1;i<=n;i++)//循環(huán)了(1+2+3+...+n)≈(n^2)/2,當(dāng)然也是O(n2)for(j=1;j<=i;j++)s++; (4) i=1;k=0;//循環(huán)了n-1≈n次,所以是O(n)while(i<=n-1){k+=10*i; i++; } (5) for(i=1;i<=n;i++)for(j=1;j<=i;j++)for(k=1;k<=j;k++)x=x+1; // 循環(huán)了(1 2+2 2+3 2+...+n 2)=n(n+1)(2n+1)/6(這個(gè)公式要記住哦)≈(n 3)/3,不考慮系數(shù),自然是O(n 3) 另外,在時(shí)間復(fù)雜度中,log 2n與lg(n)(同lg 10(n))是等價(jià)的,因?yàn)閷?duì)數(shù)換底公式: log ab=log cb/log ca 所以,log 2n=log 210 * lg(n),忽略掉系數(shù),二者當(dāng)然是等價(jià)的 二、計(jì)算方法 1.一個(gè)算法執(zhí)行所耗費(fèi)的時(shí)間,從理論上是不能算出來(lái)的,必須上機(jī)運(yùn)行測(cè)試才能知道。但我們不可能也沒(méi)有必要對(duì)每個(gè)算法都上機(jī)測(cè)試,只需知道哪個(gè)算法花費(fèi)的時(shí)間多,哪個(gè)算法花費(fèi)的時(shí)間少就可以了。
并且一個(gè)算法花費(fèi)的時(shí)間與算法中語(yǔ)句的執(zhí)行次數(shù)成正比例,哪個(gè)算法中語(yǔ)句執(zhí)行次數(shù)多,它花費(fèi)時(shí)間就多。 一個(gè)算法中的語(yǔ)句執(zhí)行次數(shù)稱為語(yǔ)句頻度或時(shí)間頻度。記為T(n)。 2.一般情況下,算法的基本操作重復(fù)執(zhí)行的次數(shù)是模塊n的某一個(gè)函數(shù)f(n),
因此,算法的時(shí)間復(fù)雜度記做:T(n)=O(f(n))。隨著模塊n的增大,算法執(zhí)行的時(shí)間的增長(zhǎng)率和f(n)的增長(zhǎng)率成正比,
所以f(n)越小,算法的時(shí)間復(fù)雜度越低,算法的效率越高。 在計(jì)算時(shí)間復(fù)雜度的時(shí)候,先找出算法的基本操作,然后根據(jù)相應(yīng)的各語(yǔ)句確定它的執(zhí)行次數(shù),
再找出T(n)的同數(shù)量級(jí)(它的同數(shù)量級(jí)有以下:1,Log 2n ,n ,nLog 2n ,n的平方,n的三次方,2的n次方,n!),
找出后,f(n)=該數(shù)量級(jí),若T(n)/f(n)求極限可得到一常數(shù)c,則時(shí)間復(fù)雜度T(n)=O(f(n))。 3.常見的時(shí)間復(fù)雜度 按數(shù)量級(jí)遞增排列,常見的時(shí)間復(fù)雜度有: 常數(shù)階O(1), 對(duì)數(shù)階O(log 2n), 線性階O(n), 線性對(duì)數(shù)階O(nlog 2n), 平方階O(n 2),
立方階O(n 3),..., k次方階O(n k), 指數(shù)階O(2 n) 。 其中, 1.O(n),O(n 2), 立方階O(n 3),..., k次方階O(n k) 為多項(xiàng)式階時(shí)間復(fù)雜度,分別稱為一階時(shí)間復(fù)雜度,二階時(shí)間復(fù)雜度。。。。 2.O(2 n),指數(shù)階時(shí)間復(fù)雜度,該種不實(shí)用 3.對(duì)數(shù)階O(log 2n), 線性對(duì)數(shù)階O(nlog 2n),除了常數(shù)階以外,該種效率最高 例:算法:for(i=1;i<=n;++i){for(j=1;j<=n;++j){c[ i ][ j ]=0; //該步驟屬于基本操作 執(zhí)行次數(shù):n 2 for(k=1;k<=n;++k)c[ i ][ j ]+=a[ i ][ k ]*b[ k ][ j ]; //該步驟屬于基本操作 執(zhí)行次數(shù):n 3 }}則有 T(n)= n 2+n 3,根據(jù)上面括號(hào)里的同數(shù)量級(jí),我們可以確定 n 3為T(n)的同數(shù)量級(jí)則有f(n)= n 3,然后根據(jù)T(n)/f(n)求極限可得到常數(shù)c則該算法的 時(shí)間復(fù)雜度:T(n)=O(n 3) 四、定義:
如果一個(gè)問(wèn)題的規(guī)模是n,解這一問(wèn)題的某一算法所需要的時(shí)間為T(n),它是n的某一函數(shù) T(n)稱為這一算法的“時(shí)間復(fù)雜性”。 當(dāng)輸入量n逐漸加大時(shí),時(shí)間復(fù)雜性的極限情形稱為算法的“漸近時(shí)間復(fù)雜性”。 我們常用大O表示法表示時(shí)間復(fù)雜性,注意它是某一個(gè)算法的時(shí)間復(fù)雜性。大O表示只是說(shuō)有上界,由定義如果f(n)=O(n),那顯然成立f(n)=O(n^2),它給你一個(gè)上界,但并不是上確界,但人們?cè)诒硎镜臅r(shí)候一般都習(xí)慣表示前者。 此外,一個(gè)問(wèn)題本身也有它的復(fù)雜性,如果某個(gè)算法的復(fù)雜性到達(dá)了這個(gè)問(wèn)題復(fù)雜性的下界,那就稱這樣的算法是最佳算法。 “大O記法”:在這種描述中使用的基本參數(shù)是 n,即問(wèn)題實(shí)例的規(guī)模,把復(fù)雜性或運(yùn)行時(shí)間表達(dá)為n的函數(shù)。這里的“O”表示量級(jí) (order),比如說(shuō)“二分檢索是 O(logn)的”,也就是說(shuō)它需要“通過(guò)logn量級(jí)的步驟去檢索一個(gè)規(guī)模為n的數(shù)組”記法 O ( f(n) )表示當(dāng) n增大時(shí),運(yùn)行時(shí)間至多將以正比于 f(n)的速度增長(zhǎng)。 這種漸進(jìn)估計(jì)對(duì)算法的理論分析和大致比較是非常有價(jià)值的,但在實(shí)踐中細(xì)節(jié)也可能造成差異。
例如,一個(gè)低附加代價(jià)的O(n2)算法在n較小的情況下可能比一個(gè)高附加代價(jià)的 O(nlogn)算法運(yùn)行得更快。
當(dāng)然,隨著n足夠大以后,具有較慢上升函數(shù)的算法必然工作得更快。 O(1) Temp=i;i=j;j=temp; 以上三條單個(gè)語(yǔ)句的頻度均為1,該程序段的執(zhí)行時(shí)間是一個(gè)與問(wèn)題規(guī)模n無(wú)關(guān)的常數(shù)。
算法的時(shí)間復(fù)雜度為常數(shù)階,記作T(n)=O(1)。如果算法的執(zhí)行時(shí)間不隨著問(wèn)題規(guī)模n的增加而增長(zhǎng),
即使算法中有上千條語(yǔ)句,其執(zhí)行時(shí)間也不過(guò)是一個(gè)較大的常數(shù)。此類算法的時(shí)間復(fù)雜度是O(1)。 O(n 2)
1) 交換i和j的內(nèi)容
sum=0; (一次)
for(i=1;i<=n;i++) (n次 )
for(j=1;j<=n;j++) (n 2次 )
sum++; (n^2次 )
解:T(n)=2n^2+n+1 =O(n^2) 2)
for (i=1;i<n;i++) {
y=y+1; //頻度是n-1
for (j=0;j<=(2*n);j++)
x++; //頻度是(n-1)*(2n+1)=2n 2-n-1
}
f(n)=2n 2-n-1+(n-1)=2n 2-2 該程序的時(shí)間復(fù)雜度T(n)=O(n 2). O(n)
3)
a=0; b=1; //頻度:2
for (i=1;i<=n;i++) //頻度: n
{
s=a+b; //頻度: n-1
b=a; //頻度:n-1
a=s; //頻度:n-1
}
T(n)=2+n+3(n-1)=4n-1=O(n).
O(log 2n )
4)
i=1; //頻度是1
while (i<=n)
i=i*2; //頻度是f(n),
則:2 f(n)<=n;f(n)<=log 2n 取最大值f(n)= log 2n, T(n)=O(log 2n ) O(n 3) 5)
for(i=0;i<n;i++) {
for(j=0;j<i;j++) {
for(k=0;k<j;k++)
x=x+2;
}
}
解:當(dāng)i=m, j=k的時(shí)候,內(nèi)層循環(huán)的次數(shù)為k當(dāng)i=m時(shí), j 可以取 0,1,...,m-1 , 所以這里最內(nèi)循環(huán)共
進(jìn)行了0+1+...+m-1=(m-1)m/2次所以,i從0取到n, 則循環(huán)共進(jìn)行了: 0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6
所以時(shí)間復(fù)雜度為O(n 3). 我們還應(yīng)該區(qū)分算法的最壞情況的行為和期望行為。如快速排序的最壞情況運(yùn)行時(shí)間是 O(n 2),
但期望時(shí)間是 O(nlogn)。通過(guò)每次都仔細(xì) 地選擇基準(zhǔn)值,我們有可能把平方情況 (即O(n 2)情況)
的概率減小到幾乎等于 0。在實(shí)際中,精心實(shí)現(xiàn)的快速排序一般都能以 (O(nlogn)時(shí)間運(yùn)行。
下面是一些常用的記法:訪問(wèn)數(shù)組中的元素是常數(shù)時(shí)間操作,或說(shuō)O(1)操作。一個(gè)算法如 果能在每個(gè)步驟去掉一半數(shù)據(jù)元素,
如二分檢索,通常它就取 O(logn)時(shí)間。用strcmp比較兩個(gè)具有n個(gè)字符的串需要O(n)時(shí)間。
常規(guī)的矩陣乘算法是O(n 3),因?yàn)樗愠雒總€(gè)元素都需要將n對(duì) 元素相乘并加到一起,所有元素的個(gè)數(shù)是n 2。
指數(shù)時(shí)間算法通常來(lái)源于需要求出所有可能結(jié)果。例如,n個(gè)元 素的集合共有2n個(gè)子集,所以要求出
所有子集的算法將是O(2n)的。指數(shù)算法一般說(shuō)來(lái)是太復(fù)雜了,除非n的值非常小,因?yàn)?#xff0c;在 這個(gè)問(wèn)題
中增加一個(gè)元素就導(dǎo)致運(yùn)行時(shí)間加倍。不幸的是,確實(shí)有許多問(wèn)題 (如著名的“巡回售貨員問(wèn)題” ),
到目前為止找到的算法都是指數(shù)的。如果我們真的遇到這種情況,通常應(yīng)該用尋找近似最佳結(jié)果的算法替代之。
?二.空間復(fù)雜度
空間復(fù)雜度(Space Complexity)是對(duì)一個(gè)算法在運(yùn)行過(guò)程中臨時(shí)占用存儲(chǔ)空間大小的量度。一個(gè)算法在計(jì)算機(jī)存儲(chǔ)器上所占用的存儲(chǔ)空間,
包括程序代碼所占用的空間,輸入數(shù)據(jù)所占用的空間和輔助變量所占用的空間這三個(gè)方面。
算法的輸入輸出數(shù)據(jù)所占用的存儲(chǔ)空間是由要解決的問(wèn)題決定的,是通過(guò)參數(shù)表由調(diào)用函數(shù)傳遞而來(lái)的,
它不隨本算法的不同而改變。存儲(chǔ)算法本身所占用的存儲(chǔ)空間與算法書寫的長(zhǎng)短成正比,要壓縮這方面的存儲(chǔ)空間,
就必須編寫出較短的算法。算法在運(yùn)行過(guò)程中臨時(shí)占用的存儲(chǔ)空間隨算法的不同而異,有的算法只需要占用少量的臨時(shí)工作單元,
而且不隨問(wèn)題規(guī)模的大小而改變,我們稱這種算法是“就地"進(jìn)行的,是節(jié)省存儲(chǔ)的算法,如這些介紹過(guò)的幾個(gè)算法都是如此;
有的算法需要占用的臨時(shí)工作單元數(shù)與解決問(wèn)題的規(guī)模n有關(guān),它隨著n的增大而增大,當(dāng)n較大時(shí),將占用較多的存儲(chǔ)單元,
例如將在第九章介紹的快速排序和歸并排序算法就屬于這種情況。分析一個(gè)算法所占用的存儲(chǔ)空間要從各方面綜合考慮。如對(duì)于遞歸算法來(lái)說(shuō),一般都比較簡(jiǎn)短,算法本身所占用的存儲(chǔ)空間較少,但運(yùn)行時(shí)需要一個(gè)附加堆棧,從而占用較多的臨時(shí)工作單元;若寫成非遞歸算法,一般可能比較長(zhǎng),算法本身占用的存儲(chǔ)空間較多,但運(yùn)行時(shí)將可能需要較少的存儲(chǔ)單元。一個(gè)算法的空間復(fù)雜度只考慮在運(yùn)行過(guò)程中為局部變量分配的存儲(chǔ)空間的大小,它包括為參數(shù)表中形參變量分配的存儲(chǔ)空間和為在函數(shù)體中定義的局部變量分配的存儲(chǔ)空間兩個(gè)部分。若一個(gè)算法為遞歸算法,其空間復(fù)雜度為遞歸所使用的堆棧空間的大小,它等于一次調(diào)用所分配的臨時(shí)存儲(chǔ)空間的大小乘以被調(diào)用的次數(shù)(即為遞歸調(diào)用的次數(shù)加1,這個(gè)1表不開始進(jìn)行的一次非遞歸調(diào)用)。算法的空間復(fù)雜度一般也以數(shù)量級(jí)的形式給出。如當(dāng)一個(gè)算法的空間復(fù)雜度為一個(gè)常量,即不隨被處理數(shù)據(jù)量n的大小而改變時(shí),可表示為O(1);當(dāng)一個(gè)算法的空間復(fù)雜度與以2為底的n的對(duì)數(shù)成正比時(shí),可表示為0(log 2n);當(dāng)一個(gè)算法的空I司復(fù)雜度與n成線性比例關(guān)系時(shí),可表示為0(n).若形參為數(shù)組,則只需要為它分配一個(gè)存儲(chǔ)由實(shí)參傳送來(lái)的一個(gè)地址指針的空間,即一個(gè)機(jī)器字長(zhǎng)空間;若形參為引用方式,則也只需要為其分配存儲(chǔ)一個(gè)地址的空間,用它來(lái)存儲(chǔ)對(duì)應(yīng)實(shí)參變量的地址,以便由系統(tǒng)自動(dòng)引用實(shí)參變量。對(duì)于一個(gè)算法,其時(shí)間復(fù)雜度和空間復(fù)雜度往往是相互影響的。當(dāng)追求一個(gè)較好的時(shí)間復(fù)雜度時(shí),可能會(huì)使空間復(fù)雜度的性能變差,即可能導(dǎo)致占用較多的存儲(chǔ)空間;反之,當(dāng)=i自求一個(gè)較好的空間復(fù)雜度時(shí),可能會(huì)使時(shí)間復(fù)雜度的性能變差,即可能導(dǎo)致占用較長(zhǎng)的運(yùn)行時(shí)間。另外,算法的所有性能之間都存在著或多或少的相互影響。因此,當(dāng)設(shè)計(jì)一個(gè)算法(特別是大型算法)時(shí),要綜合考慮算法的各項(xiàng)性能,算法的使用頻率,算法處理的數(shù)據(jù)量的大小,算法描述語(yǔ)言的特性,算法運(yùn)行的機(jī)器系統(tǒng)環(huán)境等各方面因素,才能夠設(shè)計(jì)出比較好的算法。空間復(fù)雜度是程序運(yùn)行所以需要的額外消耗存儲(chǔ)空間,也用o()來(lái)表示比如插入排序的時(shí)間復(fù)雜度是o(n 2),空間復(fù)雜度是o(1)而一般的遞歸算法就要有o(n)的空間復(fù)雜度了,因?yàn)槊看芜f歸都要存儲(chǔ)返回信息一個(gè)算法的優(yōu)劣主要從算法的執(zhí)行時(shí)間和所需要占用的存儲(chǔ)空間兩個(gè)方面衡量,算法執(zhí)行時(shí)間的度量不是采用算法執(zhí)行的絕對(duì)時(shí)間來(lái)計(jì)算的,因?yàn)橐粋€(gè)算法在不同的機(jī)器上執(zhí)行所花的時(shí)間不一樣,在不同時(shí)刻也會(huì)由于計(jì)算機(jī)資源占用情況的不同,使得算法在同一臺(tái)計(jì)算機(jī)上執(zhí)行的時(shí)間也不一樣,所以對(duì)于算法的時(shí)間復(fù)雜性,采用算法執(zhí)行過(guò)程中其基本操作的執(zhí)行次數(shù),稱為計(jì)算量來(lái)度量。算法中基本操作的執(zhí)行次數(shù)一般是與問(wèn)題規(guī)模有關(guān)的,對(duì)于結(jié)點(diǎn)個(gè)數(shù)為n的數(shù)據(jù)處理問(wèn)題,用T(n)表示算法基本操作的執(zhí)行次數(shù).在評(píng)價(jià)算法的時(shí)間復(fù)雜性時(shí),不考慮兩算法執(zhí)行次數(shù)之間的細(xì)小區(qū)別,而只關(guān)心算法的本質(zhì)差別:為此,引入一個(gè)所謂的O() 記號(hào),則T1(n)=2n=O(n),T2(n)=n+1=O(n)。一個(gè)函數(shù)f(n)是O(g(n))的,則一定存在正常數(shù)c和m,使對(duì)所有的n>m,都滿足f(n)<c*g(n)。
轉(zhuǎn)載于:https://www.cnblogs.com/yinfj/p/7126643.html
總結(jié)
以上是生活随笔為你收集整理的算法的性能评价------空间复杂度和时间复杂度的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 专家:“十三五”中国应建立覆盖城乡的超级
- 下一篇: pyodbc psutil wmi pa