版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、算法:如何分析、統(tǒng)計(jì)算法的執(zhí)行效率和資源消耗我們都知道,數(shù)據(jù)結(jié)構(gòu)和算法本身解決的是“快”和“省”的問題,即如何讓代碼運(yùn)行得更快,如何讓代碼更省存儲(chǔ)空間。所以,執(zhí)行效率是算法一個(gè)非常重要的考量指標(biāo)。那如何來(lái)衡量你編寫的算法代碼的執(zhí)行效率呢?那就要用到時(shí)間、空間復(fù)雜度分析。復(fù)雜度分析是整個(gè)算法學(xué)習(xí)的精髓,只要掌握了它,數(shù)據(jù)結(jié)構(gòu)和算法的內(nèi)容基本上就掌握了一半。為什么需要復(fù)雜度分析?事后統(tǒng)計(jì)法把代碼跑一遍,通過統(tǒng)計(jì)、監(jiān)控,就能得到算法執(zhí)行的時(shí)間和占用的內(nèi)存大小。為什么還要做時(shí)間、空間復(fù)雜度分析呢?這種分析方法能比實(shí)實(shí)在在跑一遍得到的數(shù)據(jù)更準(zhǔn)確嗎?這種評(píng)估算法執(zhí)行效率的方法是正確的。很多數(shù)據(jù)結(jié)構(gòu)和算法書
2、籍還給這種方法起了一個(gè)名字,叫事后統(tǒng)計(jì)法。但是,這種統(tǒng)計(jì)方法有非常大的局限性。測(cè)試結(jié)果非常依賴測(cè)試環(huán)境。測(cè)試環(huán)境中硬件的不同會(huì)對(duì)測(cè)試結(jié)果有很大的影響。比如,我們拿同樣一段代碼,分別用IntelCorei9處理器和IntelCorei3處理器來(lái)運(yùn)行,不用說(shuō),i9處理器要比i3處理器執(zhí)行的速度快很多。還有,比如原本在這臺(tái)機(jī)器上a代碼執(zhí)行的速度比b代碼要快,等我們換到另一臺(tái)機(jī)器上時(shí),可能會(huì)有截然相反的結(jié)果。測(cè)試結(jié)果受數(shù)據(jù)規(guī)模的影響很大。比如對(duì)同一個(gè)排序算法,待排序數(shù)據(jù)的有序度不一樣,排序的執(zhí)行時(shí)間就會(huì)有很大的差別。極端情況下,如果數(shù)據(jù)已經(jīng)是有序的,那排序算法不需要做任何操作,執(zhí)行時(shí)間就會(huì)非常短。除此
3、之外,如果測(cè)試數(shù)據(jù)規(guī)模太小,測(cè)試結(jié)果可能無(wú)法真實(shí)地反應(yīng)算法的性能。比如,對(duì)于小規(guī)模的數(shù)據(jù)排序,插入排序可能反倒會(huì)比快速排序要快!所以,我們需要一個(gè)不用具體的測(cè)試數(shù)據(jù)來(lái)測(cè)試,就可以粗略地估計(jì)算法的執(zhí)行效率的方法。大復(fù)雜度表示法算法的執(zhí)行效率,粗略地講,就是算法代碼執(zhí)行的時(shí)間。但是,如何在不運(yùn)行代碼的情況下,用“肉眼”得到一段代碼的執(zhí)行時(shí)間呢?舉個(gè)例子從CPU的角度來(lái)看,這段代碼的每一行都執(zhí)行著類似的操作:讀數(shù)據(jù)-運(yùn)算-寫數(shù)據(jù)。盡管每行代碼對(duì)應(yīng)的CPU執(zhí)行的個(gè)數(shù)、執(zhí)行的時(shí)間都不樣。但是,我們這里只是粗略估計(jì),所以可以假設(shè)每行代碼執(zhí)行的時(shí)間都一樣,為unit_time。在這個(gè)假設(shè)的基礎(chǔ)上,這段代碼的
4、總執(zhí)行時(shí)間是多少呢?第2、3行代碼分別需要1個(gè)unit_time的執(zhí)行時(shí)間,第4、5行都運(yùn)行了n遍,所以需貴n*unit_的執(zhí)行時(shí)間,所以這段代碼總的執(zhí)行時(shí)間就是(2n+2)*unit_可以看出來(lái),所有代碼的執(zhí)行時(shí)間T(n)與每行代碼的執(zhí)行次數(shù)成正比。按照這個(gè)分析思路,我們?cè)賮?lái)看這段代碼。我們依舊假設(shè)每個(gè)語(yǔ)句的執(zhí)行時(shí)間是unit_time。那這段代碼的總執(zhí)行時(shí)間T(n)是多少呢?第2、3、4行代碼,每行都需要1個(gè)unit_time的執(zhí)行時(shí)間,第5、6行代碼循環(huán)執(zhí)行了n遍,需要2n*unitjime的執(zhí)行時(shí)間,第7、8行代碼循環(huán)執(zhí)行了渺遍,所以需要2n2*unit_time的執(zhí)行時(shí)間。所以,整段
5、代碼總的執(zhí)行時(shí)間T(n)=(2n2+2n+3)*unit_time。盡管我們不知道unit_time的具體值,但是通過這兩段代碼執(zhí)行時(shí)間的推導(dǎo)過程,我們可以得到一個(gè)非常重要的規(guī)律,那就是,所有代碼的執(zhí)行時(shí)間T(n)與每行代碼的執(zhí)行次數(shù)n成正比。我們可以把這個(gè)規(guī)律總結(jié)成一個(gè)公式。注意,大O就要登場(chǎng)了!T(n)=O(f(n)其中,T(n)它表示代碼執(zhí)行的時(shí)間;n表示數(shù)據(jù)規(guī)模的大??;f(n)表示每行代碼執(zhí)行的次數(shù)總和。因?yàn)檫@是一個(gè)公式,所以用f(n)來(lái)表示,公式中的O,表示代碼的執(zhí)行時(shí)間T(n)和f(n)表達(dá)式成正比。所以,第一個(gè)例子中的T(n)=O(2n+2),第二個(gè)例子中的T(n)=(2n2+2
6、n+3)。這就是大O時(shí)間復(fù)雜度表示法。大O時(shí)間復(fù)雜度實(shí)際上并不具體表示代碼真正的執(zhí)行時(shí)間,而是表示代碼執(zhí)行時(shí)間隨數(shù)據(jù)規(guī)模增長(zhǎng)的變化趨勢(shì),所以,也叫作漸進(jìn)時(shí)間復(fù)雜度(asymptotictimecomplexity),簡(jiǎn)稱時(shí)間復(fù)雜度。當(dāng)n很大時(shí),你可以把它想象成10000、100000。而公式中的低階、常量、系數(shù)三部分并不左右增長(zhǎng)趨勢(shì),所以都可以忽略。我們只需要記錄一個(gè)最大量級(jí)就可以了,如果用大O表示法表示剛講的那兩段代碼的時(shí)間復(fù)雜度,就可以記為:T(n)=0(n);T(n)=O(n)。時(shí)間復(fù)雜度分析那如何分析一段代碼的時(shí)間復(fù)雜度呢?下面舉了三個(gè)比較實(shí)用的方法只關(guān)注循環(huán)執(zhí)行次數(shù)最多的一段代碼大0
7、這種復(fù)雜度表示方法只是表示一種變化趨勢(shì)。我們通常會(huì)忽略掉公式中的常量、低階、系數(shù),只需要記錄一個(gè)最大階的量級(jí)就可以了。所以,我們?cè)诜治鲆粋€(gè)算法、一段代碼的時(shí)間復(fù)雜度的時(shí)候,也只需要關(guān)注循環(huán)次數(shù)最多的那一段代碼就可以了舉個(gè)例子:其中第2、3行代碼都是常量級(jí)的執(zhí)行時(shí)間,與n的大小無(wú)關(guān),所以對(duì)于復(fù)雜度并沒有影響。循環(huán)執(zhí)行次數(shù)最多的是第4、5行代碼,所以這塊代碼要重點(diǎn)分析。這兩行代碼被執(zhí)行了n次,所以總的時(shí)間復(fù)雜度就是0(n)。加法法則:總復(fù)雜度等于量級(jí)最大的那段代碼的復(fù)雜度舉個(gè)例子:10111213141516171BW2021222324這個(gè)代碼分為三部分,分別是求sum_1、sum_2、sum_
8、3。我們可以分別分析每一部分的時(shí)間復(fù)雜度,然后把它們放到一塊兒,再取一個(gè)量級(jí)最大的作為整段代碼的復(fù)雜度。第一段的時(shí)間復(fù)雜度是多少呢?這段代碼循環(huán)執(zhí)行了100次,所以是一個(gè)常量的執(zhí)行時(shí)間,跟n的規(guī)模無(wú)關(guān)。這里再?gòu)?qiáng)調(diào)一下,即便這段代碼循環(huán)1000000次,10000000000次,只要是一個(gè)已知的數(shù),跟n無(wú)關(guān),照樣也是常量級(jí)的執(zhí)行時(shí)間。當(dāng)n無(wú)限大時(shí),就可以忽略。盡管對(duì)代碼的執(zhí)行時(shí)間會(huì)有很大影響,但是回到時(shí)間復(fù)雜度的概念來(lái)說(shuō),它表示的是一個(gè)算法執(zhí)行效率與數(shù)據(jù)規(guī)模增長(zhǎng)的變化趨勢(shì),所以不管常量的執(zhí)行時(shí)間多大,我們都可以忽略掉。因?yàn)樗旧韺?duì)增長(zhǎng)趨勢(shì)沒有影響。那第二段代碼和第三段代碼的時(shí)間復(fù)雜度是多少呢?答
9、案是O(n)和0卩2)綜合這三段代碼的時(shí)間復(fù)雜度,我們?nèi)∑渲凶畲蟮牧考?jí)。所以,整段代碼的時(shí)間復(fù)雜度就為O卩2)。也就是說(shuō),總的時(shí)間復(fù)雜度就等于量級(jí)最大的那段代碼的時(shí)間復(fù)雜度。那我們將這個(gè)規(guī)律抽象成公式就是:如果T1(n)=O(f(n),T2(n)=O(g(n);那么T(n)=T1(n)+T2(n)=max(O(f(n),O(g(n)=O(max(f(n),g(n).乘法法則:嵌套代碼的復(fù)雜度等于嵌套內(nèi)外代碼復(fù)雜度的成績(jī)乘法法則:如果T1(n)=O(f(n),T2(n)=O(g(n);那么T(n)=T1(n)*T2(n)=O(f(n)*O(g(n)=O(f(n)*g(n).也就是說(shuō),假設(shè)T1(n
10、)=O(n),T2(n)=O(n2),則T1(n)*T2(n)=O(n3)。落實(shí)到具體的代碼上,我們可以把乘法法則看成是嵌套循環(huán),舉個(gè)例子:10111213141518我們單獨(dú)看cal()函數(shù)。假設(shè)f()只是一個(gè)普通的操作,那第46行的時(shí)間復(fù)雜度就是,T1(n)=0(n)。但f()函數(shù)本身不是一個(gè)簡(jiǎn)單的操作,它的時(shí)間復(fù)雜度是T2(n)=0(n),所以,整個(gè)cal()函數(shù)的時(shí)間復(fù)雜度就是,T(n)=T1(n)*T2(n)=0(n*n)=0(n2)o幾種常見時(shí)間復(fù)雜度實(shí)例分析雖然代碼千差萬(wàn)別,但是常見的復(fù)雜度量級(jí)并不多??偨Y(jié)如下傳牛a電級(jí)I昭溼吐檢盤報(bào)并ol)歇細(xì)J05”號(hào)耐OU1).tXrf對(duì)上
11、面羅列的復(fù)雜度量級(jí),我們可以粗略地分為兩類,多項(xiàng)式量級(jí)和非多項(xiàng)式量級(jí)。其中,非多項(xiàng)式量級(jí)只有兩個(gè):02)和0(n!)o當(dāng)數(shù)據(jù)規(guī)模n越來(lái)越大時(shí),非多項(xiàng)式量級(jí)算法的執(zhí)行時(shí)間會(huì)急劇增加,求解問題的執(zhí)行時(shí)間會(huì)無(wú)限增長(zhǎng)。所以,非多項(xiàng)式時(shí)間復(fù)雜度的算法其實(shí)是非常低效的算法。因此,幾乎不常見。我們主要來(lái)看幾種常見的多項(xiàng)式時(shí)間復(fù)雜度。O(1)首先必須明確的是,0(1)只是常量級(jí)時(shí)間復(fù)雜度的一種表示方法,并不是指只執(zhí)行了一行代碼。比如這段代碼,即便只有3行,它的時(shí)間復(fù)雜度也是0(1),而不是0(3)。總的來(lái)說(shuō),只要代碼的執(zhí)行時(shí)間不隨n的增大而增長(zhǎng),這樣代碼的時(shí)間復(fù)雜度我們都記作0(1)?;蛘哒f(shuō),一般情況下,只要
12、算法中不存在循環(huán)語(yǔ)句、遞歸語(yǔ)句,即便有成千上萬(wàn)行的代碼,其時(shí)間復(fù)雜度也是0(1)O(logn)、O(nlogn)對(duì)數(shù)階時(shí)間復(fù)雜度非常常見,同時(shí)也是最難分析的一種時(shí)間復(fù)雜度。舉個(gè)例子根據(jù)我們前面講的復(fù)雜度分析方法,第三行代碼是循環(huán)執(zhí)行次數(shù)最多的。所以,我們只要能計(jì)算出這行代碼被執(zhí)行了多少次,就能知道整段代碼的時(shí)間復(fù)雜度。從代碼中可以看出,變量i的值從1開始取,每循環(huán)一次就乘以2。當(dāng)大于n時(shí),循環(huán)結(jié)束。還記得我們高中學(xué)過的等比數(shù)列嗎?實(shí)際上,變量i的取值就是一個(gè)等比數(shù)列。如果我把它一個(gè)一個(gè)列出來(lái),就應(yīng)該是這個(gè)樣子的:所以,我們只要知道x值是多少,就知道這行代碼執(zhí)行的次數(shù)了。通過2=n求解x這個(gè)問題
13、我們想高中應(yīng)該就學(xué)過了,我就不多說(shuō)了。x=logn,所以,這段代碼的時(shí)間復(fù)雜度就是OQog?。那下面代碼的時(shí)間復(fù)雜度是多少?很簡(jiǎn)單就能看出來(lái),這段代碼的時(shí)間復(fù)雜度為O(log3n)。實(shí)際上,不管是以2為底,還是以3為底,還是以10為底,我們可以把所有對(duì)數(shù)階的時(shí)間復(fù)雜度都記為O(lognlognlogn)。為什么呢?我們知道,對(duì)數(shù)之間是可以互相轉(zhuǎn)換的,logn就等于log2*logn,所以O(shè)ogn)=O(C*logn,其中C=logl是個(gè)常量?;谖覀兦懊娴囊粋€(gè)理論:在采用大O標(biāo)記復(fù)雜度的時(shí)候,可以忽略系數(shù),即O(Cf(n)=O(f(n)。所以,O(log_2n)就等于O(log_3n)。因此,
14、在對(duì)數(shù)階時(shí)間復(fù)雜度的表示方法里,我們忽略對(duì)數(shù)的“底”,統(tǒng)一表示為O(logn)。那O(nlogn)有怎么理解呢?根據(jù)乘法法則,如果一段代碼的時(shí)間復(fù)雜度是0(lognlognlogn),我們循環(huán)執(zhí)行n遍,時(shí)間復(fù)雜度就是0(nlogn)。而且,0(nlogn)也是一種非常常見的算法時(shí)間復(fù)雜度。比如,歸并排序、快速排序的時(shí)間復(fù)雜度都是0(nlogn)。O(m+n)、O(m*n)我們?cè)賮?lái)講一種跟前面都不一樣的時(shí)間復(fù)雜度,代碼的時(shí)間復(fù)雜度有兩個(gè)數(shù)據(jù)的規(guī)模決定。舉個(gè)例子從代碼中可以看出,m和n是表示兩個(gè)數(shù)據(jù)規(guī)模。我們無(wú)法事先評(píng)估m(xù)和n誰(shuí)的量級(jí)大,所以我們?cè)诒硎緩?fù)雜度的時(shí)候,就不能簡(jiǎn)單地利用加法法則,省略掉其中一個(gè)。所以,上面代碼的時(shí)間復(fù)雜度就是0(m+n)。針對(duì)這種情況,原來(lái)的加法法則就不正確了,我們需要將加法規(guī)則改為:T1(m)+T2(n)=O(f(m)+g(n)。但是乘法法則繼續(xù)有效:T1(m)*T2(n)=O(f(m)*f(n)??臻g復(fù)雜度分析時(shí)間復(fù)雜度的全稱是漸進(jìn)時(shí)間復(fù)雜度,表示算法的執(zhí)行時(shí)間與數(shù)據(jù)規(guī)模之間的增長(zhǎng)關(guān)系??臻g復(fù)雜度的全稱是漸進(jìn)空間復(fù)雜度,表示算法的存儲(chǔ)時(shí)間與數(shù)據(jù)規(guī)模之間的增長(zhǎng)關(guān)系看個(gè)例子:跟時(shí)間復(fù)雜度分析一樣,我們可以看到,第2行代碼中,我們申請(qǐng)了一個(gè)空間存儲(chǔ)變量i,但是它是常量階的,跟數(shù)據(jù)規(guī)模n沒有關(guān)系,所以我們可以忽略。第3行申請(qǐng)了一個(gè)大小為n的int類型
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 提高品牌關(guān)注度擴(kuò)大市場(chǎng)影響力計(jì)劃
- 如何引導(dǎo)品牌發(fā)展的未來(lái)方向計(jì)劃
- 行業(yè)動(dòng)態(tài)分析與趨勢(shì)預(yù)測(cè)計(jì)劃
- 疫情期間的應(yīng)對(duì)措施與總結(jié)計(jì)劃
- 行為規(guī)范與獎(jiǎng)懲機(jī)制建立計(jì)劃
- 與書友共成長(zhǎng)拓展幼兒園小班的閱讀興趣計(jì)劃
- 促進(jìn)師生互動(dòng)的班級(jí)活動(dòng)設(shè)計(jì)計(jì)劃
- 火災(zāi)煙霧中的自救技能培訓(xùn)
- 搪陶之美:科技與藝術(shù)的交融-瓷藝制品工藝詳解與應(yīng)用領(lǐng)域探索
- 2022年高考語(yǔ)文作文的題目預(yù)測(cè)及相應(yīng)范文
- 小學(xué)道德與法治-我也有責(zé)任教學(xué)設(shè)計(jì)學(xué)情分析教材分析課后反思
- 危險(xiǎn)化學(xué)品經(jīng)營(yíng)單位負(fù)責(zé)人和安全管理人員培訓(xùn)課件
- 新能源提車檢查表
- 檢察院監(jiān)督申請(qǐng)書【4篇】
- 變壓器油耐壓標(biāo)準(zhǔn)
- 疑似預(yù)防接種異常反應(yīng)(AEFI)監(jiān)測(cè)及處理課件
- 中醫(yī)感冒辨證施治課件
- 污水處理站施工組織設(shè)計(jì)-完整版
- 經(jīng)濟(jì)日用文書-條據(jù)告啟
- 鏟車考試題庫(kù)
- GB/T 38472-2023再生鑄造鋁合金原料
評(píng)論
0/150
提交評(píng)論