大话数据结构之算法 时间复杂度
http://www.cnblogs.com/danyingjie/archive/2011/11/17/2252466.html
時間復(fù)雜度用O()來體現(xiàn),我們稱之為大O記法。記做:T(n)=O(f(n))
一般情況下隨著n的增大,T(n)增長最慢的算法為最優(yōu)算法。
O(1)叫常數(shù)階 O(n)叫線性階 O(n2)叫平方階
?
推倒大O階
1.?????? 用常數(shù)1取代運(yùn)行時間中的所有加法常數(shù)
2.?????? 在修改后的運(yùn)行次數(shù)函數(shù)中,只保留最高階項。
3.?????? 如果最高階項存在且不是1,則去除與這個項相乘的常數(shù)。
得到的結(jié)果就是大O階。
?
對于高斯算法而言,這個算法的運(yùn)行次數(shù)函數(shù)是f(n)=3,根據(jù)我們推導(dǎo)大O階的方法,第一步就是把常數(shù)項3改為1。在保留最高階項時發(fā)現(xiàn),它根本沒有最高階項,所以這個算法的時間復(fù)雜度為O(1)。
?
對于分支結(jié)構(gòu)而言,無論是真,還是假,執(zhí)行的次數(shù)都是恒定的,不會隨著n的變大而發(fā)生變化,所以單純的分支結(jié)構(gòu)(不包含在循環(huán)結(jié)構(gòu)中),其時間復(fù)雜度也是O(1)。
?
線性階:
Int I;
For(i=0;i<n;i++)
{
?
}
因為循環(huán)體中的代碼要執(zhí)行N次,所以它的循環(huán)的時間復(fù)雜度為O(n)。
?
對數(shù)階:
Int count=1;
While (count<n)
{
?? Count=count*2;
}
由于每次count乘以2以后,就距離n更近了一分。也就是,有多少個2相乘以后大于n,則會退出循環(huán)。由 2x=n 得到x=log2n。所以這個循環(huán)的時間復(fù)雜度為O(logn)
?
?
最壞情況運(yùn)行時間是一種保證,那就是運(yùn)行時間將不會再壞了。在應(yīng)用中,這是一種最重要的需求,通常,除非特別指定,我們提到的運(yùn)行時間都是最壞情況的運(yùn)行時間。
?
?
算法空間復(fù)雜度通過計算算法所需的存儲空間實現(xiàn),算法空間復(fù)雜度的計算公式記做:S(n)=O(f(n)),其中n為問題的規(guī)模,f(n)為語句關(guān)于n所占存儲空間的函數(shù)。
常見的時間復(fù)雜度所耗時間的大小排列
O(1)<O(logn)<O(n)<O(nlogn)<O(n2)
?
http://blog.csdn.net/hitwhylz/article/details/12374407
算法的時間復(fù)雜度定義為:
在進(jìn)行算法分析時,語句總的執(zhí)行次數(shù)T(n)是關(guān)于問題規(guī)模n的函數(shù),進(jìn)而分析T(n)隨n的變化情況并確定T(n)的數(shù)量級。算法的時間復(fù)雜度,也就是算法的時間量度,記作:T(n}=0(f(n))。它表示隨問題規(guī)模n的增大,算法執(zhí)行時間的埔長率和 f(n)的埔長率相同,稱作算法的漸近時間復(fù)雜度,簡稱為時間復(fù)雜度。其中f( n)是問題規(guī)橫n的某個函數(shù)。
根據(jù)定義,求解算法的時間復(fù)雜度的具體步驟是:
⑴ 找出算法中的基本語句;
算法中執(zhí)行次數(shù)最多的那條語句就是基本語句,通常是最內(nèi)層循環(huán)的循環(huán)體。
⑵ 計算基本語句的執(zhí)行次數(shù)的數(shù)量級;
只需計算基本語句執(zhí)行次數(shù)的數(shù)量級,這就意味著只要保證基本語句執(zhí)行次數(shù)的函數(shù)中的最高次冪正確即可,可以忽略所有低次冪和最高次冪的系數(shù)。這樣能夠簡化算法分析,并且使注意力集中在最重要的一點上:增長率。
⑶ 用大Ο記號表示算法的時間性能。
將基本語句執(zhí)行次數(shù)的數(shù)量級放入大Ο記號中。
如何推導(dǎo)大o階呢?我們給出了下面 的推導(dǎo)方法:
1.用常數(shù)1取代運(yùn)行時間中的所有加法常數(shù)。
2.在修改后的運(yùn)行次數(shù)函數(shù)中,只保留最髙階項。
3.如果最高階項存在且不是1,則去除與這個項相乘的常數(shù)。
簡單的說,就是保留求出次數(shù)的最高次冪,并且把系數(shù)去掉。 ?如T(n)=2n^2+n+1 =O(n^2)
舉個例子。
[cpp] view plaincopyprint?
?
按照上面推導(dǎo)“大O階”的步驟,我們來看
第一步:“用常數(shù) 1 取代運(yùn)行時間中的所有加法常數(shù)”,
則上面的算式變?yōu)?#xff1a;執(zhí)行總次數(shù) =3n^2 + 3n + 1
(直接相加的話,應(yīng)該是T(n) = 1 + n+1 + n + n*(n+1) + n*n + n*n + 1 = 3n^2 + 3n + 3。現(xiàn)在用常數(shù) 1 取代運(yùn)行時間中的所有加法常數(shù),就是把T(n) = 3n^2 + 3n + 3中的最后一個3改為1. 就得到了 T(n) = 3n^2 + 3n + 1)
?
第二步:“在修改后的運(yùn)行次數(shù)函數(shù)中,只保留最高階項”。
這里的最高階是 n 的二次方,所以算式變?yōu)?#xff1a;執(zhí)行總次數(shù) = 3n^2
?
第三步:“如果最高階項存在且不是 1 ,則去除與這個項相乘的常數(shù)”。
這里 n 的二次方不是 1 所以要去除這個項的相乘常數(shù),算式變?yōu)?#xff1a;執(zhí)行總次數(shù) = n^2
因此最后我們得到上面那段代碼的算法時間復(fù)雜度表示為: O( n^2 )
下面我把常見的算法時間復(fù)雜度以及他們在效率上的高低順序記錄在這里,使大家對算法的效率有個直觀的認(rèn)識。
O(1) 常數(shù)階 < O(logn) 對數(shù)階 < O(n) 線性階 < O(nlogn) < O(n^2) 平方階 < O(n^3) < { O(2^n) < O(n!) < O(n^n) }
最后三項用大括號把他們括起來是想要告訴大家,如果日后大家設(shè)計的算法推導(dǎo)出的“大O階”是大括號中的這幾位,那么趁早放棄這個算法,在去研究新的算法出來吧。因為大括號中的這幾位即便是在 n 的規(guī)模比較小的情況下仍然要耗費(fèi)大量的時間,算法的時間復(fù)雜度大的離譜,基本上就是“不可用狀態(tài)”。
好了,原理就介紹到這里了。下面通過幾個例子具體分析下時間復(fù)雜度計算過程。
一。計算 1 + 2 + 3 + 4 + ...... + 100。
常規(guī)算法,代碼如下:
[cpp] view plaincopyprint?
從代碼附加的注釋可以看到所有代碼都執(zhí)行了多少次。那么這寫代碼語句執(zhí)行次數(shù)的總和就可以理解為是該算法計算出結(jié)果所需要的時間。該算法所用的時間(算法語句執(zhí)行的總次數(shù))為: 1 + ( n + 1 ) + n + 1 = 2n + 3
而當(dāng) n 不斷增大,比如我們這次所要計算的不是 1 + 2 + 3 + 4 + ...... + 100 = ? 而是 1 + 2 + 3 + 4 + ...... + n = ?其中 n 是一個十分大的數(shù)字,那么由此可見,上述算法的執(zhí)行總次數(shù)(所需時間)會隨著 n 的增大而增加,但是在 for 循環(huán)以外的語句并不受 n 的規(guī)模影響(永遠(yuǎn)都只執(zhí)行一次)。所以我們可以將上述算法的執(zhí)行總次數(shù)簡單的記做: 2n 或者簡記 n
這樣我們就得到了我們設(shè)計的算法的時間復(fù)雜度,我們把它記作: O(n)
再來看看高斯的算法,代碼如下:
這個算法的時間復(fù)雜度: O(3),但一般記作 O(1)。
從感官上我們就不難看出,從算法的效率上看,O(1) < O(n) 的,所以高斯的算法更快,更優(yōu)秀。
這也就難怪為什么每本算法書開篇都是拿高斯的這個例子來舉例了(至少我看的都是)...人家也確實有那個資本。
二。求兩個n階方陣C=A*B的乘積其算法如下:
[cpp] view plaincopyprint?則該算法所有語句的頻度之和為:
T(n) = 2n^3+3n^2+2n+1; ?利用大O表示法,該算法的時間復(fù)雜度為O(n^3)。
三。分析下列時間復(fù)雜度
[cpp] view plaincopyprint?
設(shè)for循環(huán)語句執(zhí)行次數(shù)為T(n),則 i = 2T(n) + 1 <= n - 1, ?即T(n) <= n/2 - 1 = O(n)
四。分析下列時間復(fù)雜度
[cpp] view plaincopyprint?
其中,算法的基本運(yùn)算語句是
if (b[k] > b[j])
{
? ?k = j;
}
其執(zhí)行次數(shù)T(n)為:
五。分析下列時間復(fù)雜度
[cpp] view plaincopyprint?
?
其中,算法的基本運(yùn)算語句即while循環(huán)內(nèi)部分,
設(shè)while循環(huán)語句執(zhí)行次數(shù)為T(n),則
六。Hanoi(遞歸算法)時間復(fù)雜度分析
[cpp] view plaincopyprint?
對于遞歸函數(shù)的分析,跟設(shè)計遞歸函數(shù)一樣,要先考慮基情況(比如hanoi中n==1時候),這樣把一個大問題劃分為多個子問題的求解。
故此上述算法的時間復(fù)雜度的遞歸關(guān)系如下:
?
總結(jié)
以上是生活随笔為你收集整理的大话数据结构之算法 时间复杂度的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入Java核心 探秘Java垃圾回收机
- 下一篇: uml学习入门