版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、算法:如何分析、統(tǒng)計算法的執(zhí)行效率和資源消耗我們都知道,數(shù)據(jù)結(jié)構(gòu)和算法本身解決的是“快”和“省”的問題,即如何讓代碼運行得更快,如何讓代碼更省存儲空間。所以,執(zhí)行效率是算法一個非常重要的考量指標(biāo)。那如何來衡量你編寫的算法代碼的執(zhí)行效率呢?那就要用到時間、空間復(fù)雜度分析。復(fù)雜度分析是整個算法學(xué)習(xí)的精髓,只要掌握了它,數(shù)據(jù)結(jié)構(gòu)和算法的內(nèi)容基本上就掌握了一半。為什么需要復(fù)雜度分析?事后統(tǒng)計法把代碼跑一遍,通過統(tǒng)計、監(jiān)控,就能得到算法執(zhí)行的時間和占用的內(nèi)存大小。為什么還要做時間、空間復(fù)雜度分析呢?這種分析方法能比實實在在跑一遍得到的數(shù)據(jù)更準(zhǔn)確嗎?這種評估算法執(zhí)行效率的方法是正確的。很多數(shù)據(jù)結(jié)構(gòu)和算法書
2、籍還給這種方法起了一個名字,叫事后統(tǒng)計法。但是,這種統(tǒng)計方法有非常大的局限性。測試結(jié)果非常依賴測試環(huán)境。測試環(huán)境中硬件的不同會對測試結(jié)果有很大的影響。比如,我們拿同樣一段代碼,分別用IntelCorei9處理器和IntelCorei3處理器來運行,不用說,i9處理器要比i3處理器執(zhí)行的速度快很多。還有,比如原本在這臺機器上a代碼執(zhí)行的速度比b代碼要快,等我們換到另一臺機器上時,可能會有截然相反的結(jié)果。測試結(jié)果受數(shù)據(jù)規(guī)模的影響很大。比如對同一個排序算法,待排序數(shù)據(jù)的有序度不一樣,排序的執(zhí)行時間就會有很大的差別。極端情況下,如果數(shù)據(jù)已經(jīng)是有序的,那排序算法不需要做任何操作,執(zhí)行時間就會非常短。除此
3、之外,如果測試數(shù)據(jù)規(guī)模太小,測試結(jié)果可能無法真實地反應(yīng)算法的性能。比如,對于小規(guī)模的數(shù)據(jù)排序,插入排序可能反倒會比快速排序要快!所以,我們需要一個不用具體的測試數(shù)據(jù)來測試,就可以粗略地估計算法的執(zhí)行效率的方法。大復(fù)雜度表示法算法的執(zhí)行效率,粗略地講,就是算法代碼執(zhí)行的時間。但是,如何在不運行代碼的情況下,用“肉眼”得到一段代碼的執(zhí)行時間呢?舉個例子從CPU的角度來看,這段代碼的每一行都執(zhí)行著類似的操作:讀數(shù)據(jù)-運算-寫數(shù)據(jù)。盡管每行代碼對應(yīng)的CPU執(zhí)行的個數(shù)、執(zhí)行的時間都不樣。但是,我們這里只是粗略估計,所以可以假設(shè)每行代碼執(zhí)行的時間都一樣,為unit_time。在這個假設(shè)的基礎(chǔ)上,這段代碼的
4、總執(zhí)行時間是多少呢?第2、3行代碼分別需要1個unit_time的執(zhí)行時間,第4、5行都運行了n遍,所以需貴n*unit_的執(zhí)行時間,所以這段代碼總的執(zhí)行時間就是(2n+2)*unit_可以看出來,所有代碼的執(zhí)行時間T(n)與每行代碼的執(zhí)行次數(shù)成正比。按照這個分析思路,我們再來看這段代碼。我們依舊假設(shè)每個語句的執(zhí)行時間是unit_time。那這段代碼的總執(zhí)行時間T(n)是多少呢?第2、3、4行代碼,每行都需要1個unit_time的執(zhí)行時間,第5、6行代碼循環(huán)執(zhí)行了n遍,需要2n*unitjime的執(zhí)行時間,第7、8行代碼循環(huán)執(zhí)行了渺遍,所以需要2n2*unit_time的執(zhí)行時間。所以,整段
5、代碼總的執(zhí)行時間T(n)=(2n2+2n+3)*unit_time。盡管我們不知道unit_time的具體值,但是通過這兩段代碼執(zhí)行時間的推導(dǎo)過程,我們可以得到一個非常重要的規(guī)律,那就是,所有代碼的執(zhí)行時間T(n)與每行代碼的執(zhí)行次數(shù)n成正比。我們可以把這個規(guī)律總結(jié)成一個公式。注意,大O就要登場了!T(n)=O(f(n)其中,T(n)它表示代碼執(zhí)行的時間;n表示數(shù)據(jù)規(guī)模的大?。籪(n)表示每行代碼執(zhí)行的次數(shù)總和。因為這是一個公式,所以用f(n)來表示,公式中的O,表示代碼的執(zhí)行時間T(n)和f(n)表達(dá)式成正比。所以,第一個例子中的T(n)=O(2n+2),第二個例子中的T(n)=(2n2+2
6、n+3)。這就是大O時間復(fù)雜度表示法。大O時間復(fù)雜度實際上并不具體表示代碼真正的執(zhí)行時間,而是表示代碼執(zhí)行時間隨數(shù)據(jù)規(guī)模增長的變化趨勢,所以,也叫作漸進(jìn)時間復(fù)雜度(asymptotictimecomplexity),簡稱時間復(fù)雜度。當(dāng)n很大時,你可以把它想象成10000、100000。而公式中的低階、常量、系數(shù)三部分并不左右增長趨勢,所以都可以忽略。我們只需要記錄一個最大量級就可以了,如果用大O表示法表示剛講的那兩段代碼的時間復(fù)雜度,就可以記為:T(n)=0(n);T(n)=O(n)。時間復(fù)雜度分析那如何分析一段代碼的時間復(fù)雜度呢?下面舉了三個比較實用的方法只關(guān)注循環(huán)執(zhí)行次數(shù)最多的一段代碼大0
7、這種復(fù)雜度表示方法只是表示一種變化趨勢。我們通常會忽略掉公式中的常量、低階、系數(shù),只需要記錄一個最大階的量級就可以了。所以,我們在分析一個算法、一段代碼的時間復(fù)雜度的時候,也只需要關(guān)注循環(huán)次數(shù)最多的那一段代碼就可以了舉個例子:其中第2、3行代碼都是常量級的執(zhí)行時間,與n的大小無關(guān),所以對于復(fù)雜度并沒有影響。循環(huán)執(zhí)行次數(shù)最多的是第4、5行代碼,所以這塊代碼要重點分析。這兩行代碼被執(zhí)行了n次,所以總的時間復(fù)雜度就是0(n)。加法法則:總復(fù)雜度等于量級最大的那段代碼的復(fù)雜度舉個例子:10111213141516171BW2021222324這個代碼分為三部分,分別是求sum_1、sum_2、sum_
8、3。我們可以分別分析每一部分的時間復(fù)雜度,然后把它們放到一塊兒,再取一個量級最大的作為整段代碼的復(fù)雜度。第一段的時間復(fù)雜度是多少呢?這段代碼循環(huán)執(zhí)行了100次,所以是一個常量的執(zhí)行時間,跟n的規(guī)模無關(guān)。這里再強調(diào)一下,即便這段代碼循環(huán)1000000次,10000000000次,只要是一個已知的數(shù),跟n無關(guān),照樣也是常量級的執(zhí)行時間。當(dāng)n無限大時,就可以忽略。盡管對代碼的執(zhí)行時間會有很大影響,但是回到時間復(fù)雜度的概念來說,它表示的是一個算法執(zhí)行效率與數(shù)據(jù)規(guī)模增長的變化趨勢,所以不管常量的執(zhí)行時間多大,我們都可以忽略掉。因為它本身對增長趨勢沒有影響。那第二段代碼和第三段代碼的時間復(fù)雜度是多少呢?答
9、案是O(n)和0卩2)綜合這三段代碼的時間復(fù)雜度,我們?nèi)∑渲凶畲蟮牧考墶K?,整段代碼的時間復(fù)雜度就為O卩2)。也就是說,總的時間復(fù)雜度就等于量級最大的那段代碼的時間復(fù)雜度。那我們將這個規(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ù)雜度的成績乘法法則:如果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).也就是說,假設(shè)T1(n
10、)=O(n),T2(n)=O(n2),則T1(n)*T2(n)=O(n3)。落實到具體的代碼上,我們可以把乘法法則看成是嵌套循環(huán),舉個例子:10111213141518我們單獨看cal()函數(shù)。假設(shè)f()只是一個普通的操作,那第46行的時間復(fù)雜度就是,T1(n)=0(n)。但f()函數(shù)本身不是一個簡單的操作,它的時間復(fù)雜度是T2(n)=0(n),所以,整個cal()函數(shù)的時間復(fù)雜度就是,T(n)=T1(n)*T2(n)=0(n*n)=0(n2)o幾種常見時間復(fù)雜度實例分析雖然代碼千差萬別,但是常見的復(fù)雜度量級并不多??偨Y(jié)如下傳牛a電級I昭溼吐檢盤報并ol)歇細(xì)J05”號耐OU1).tXrf對上
11、面羅列的復(fù)雜度量級,我們可以粗略地分為兩類,多項式量級和非多項式量級。其中,非多項式量級只有兩個:02)和0(n!)o當(dāng)數(shù)據(jù)規(guī)模n越來越大時,非多項式量級算法的執(zhí)行時間會急劇增加,求解問題的執(zhí)行時間會無限增長。所以,非多項式時間復(fù)雜度的算法其實是非常低效的算法。因此,幾乎不常見。我們主要來看幾種常見的多項式時間復(fù)雜度。O(1)首先必須明確的是,0(1)只是常量級時間復(fù)雜度的一種表示方法,并不是指只執(zhí)行了一行代碼。比如這段代碼,即便只有3行,它的時間復(fù)雜度也是0(1),而不是0(3)??偟膩碚f,只要代碼的執(zhí)行時間不隨n的增大而增長,這樣代碼的時間復(fù)雜度我們都記作0(1)?;蛘哒f,一般情況下,只要
12、算法中不存在循環(huán)語句、遞歸語句,即便有成千上萬行的代碼,其時間復(fù)雜度也是0(1)O(logn)、O(nlogn)對數(shù)階時間復(fù)雜度非常常見,同時也是最難分析的一種時間復(fù)雜度。舉個例子根據(jù)我們前面講的復(fù)雜度分析方法,第三行代碼是循環(huán)執(zhí)行次數(shù)最多的。所以,我們只要能計算出這行代碼被執(zhí)行了多少次,就能知道整段代碼的時間復(fù)雜度。從代碼中可以看出,變量i的值從1開始取,每循環(huán)一次就乘以2。當(dāng)大于n時,循環(huán)結(jié)束。還記得我們高中學(xué)過的等比數(shù)列嗎?實際上,變量i的取值就是一個等比數(shù)列。如果我把它一個一個列出來,就應(yīng)該是這個樣子的:所以,我們只要知道x值是多少,就知道這行代碼執(zhí)行的次數(shù)了。通過2=n求解x這個問題
13、我們想高中應(yīng)該就學(xué)過了,我就不多說了。x=logn,所以,這段代碼的時間復(fù)雜度就是OQog?。那下面代碼的時間復(fù)雜度是多少?很簡單就能看出來,這段代碼的時間復(fù)雜度為O(log3n)。實際上,不管是以2為底,還是以3為底,還是以10為底,我們可以把所有對數(shù)階的時間復(fù)雜度都記為O(lognlognlogn)。為什么呢?我們知道,對數(shù)之間是可以互相轉(zhuǎn)換的,logn就等于log2*logn,所以O(shè)ogn)=O(C*logn,其中C=logl是個常量?;谖覀兦懊娴囊粋€理論:在采用大O標(biāo)記復(fù)雜度的時候,可以忽略系數(shù),即O(Cf(n)=O(f(n)。所以,O(log_2n)就等于O(log_3n)。因此,
14、在對數(shù)階時間復(fù)雜度的表示方法里,我們忽略對數(shù)的“底”,統(tǒng)一表示為O(logn)。那O(nlogn)有怎么理解呢?根據(jù)乘法法則,如果一段代碼的時間復(fù)雜度是0(lognlognlogn),我們循環(huán)執(zhí)行n遍,時間復(fù)雜度就是0(nlogn)。而且,0(nlogn)也是一種非常常見的算法時間復(fù)雜度。比如,歸并排序、快速排序的時間復(fù)雜度都是0(nlogn)。O(m+n)、O(m*n)我們再來講一種跟前面都不一樣的時間復(fù)雜度,代碼的時間復(fù)雜度有兩個數(shù)據(jù)的規(guī)模決定。舉個例子從代碼中可以看出,m和n是表示兩個數(shù)據(jù)規(guī)模。我們無法事先評估m(xù)和n誰的量級大,所以我們在表示復(fù)雜度的時候,就不能簡單地利用加法法則,省略掉其中一個。所以,上面代碼的時間復(fù)雜度就是0(m+n)。針對這種情況,原來的加法法則就不正確了,我們需要將加法規(guī)則改為:T1(m)+T2(n)=O(f(m)+g(n)。但是乘法法則繼續(xù)有效:T1(m)*T2(n)=O(f(m)*f(n)??臻g復(fù)雜度分析時間復(fù)雜度的全稱是漸進(jìn)時間復(fù)雜度,表示算法的執(zhí)行時間與數(shù)據(jù)規(guī)模之間的增長關(guān)系??臻g復(fù)雜度的全稱是漸進(jìn)空間復(fù)雜度,表示算法的存儲時間與數(shù)據(jù)規(guī)模之間的增長關(guān)系看個例子:跟時間復(fù)雜度分析一樣,我們可以看到,第2行代碼中,我們申請了一個空間存儲變量i,但是它是常量階的,跟數(shù)據(jù)規(guī)模n沒有關(guān)系,所以我們可以忽略。第3行申請了一個大小為n的int類型
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 個人住宅裝潢協(xié)議范本(2024年修訂)版
- 2025年度叉車安全操作培訓(xùn)課程優(yōu)化與推廣合同4篇
- 2025版廠房買賣及土地使用權(quán)變更與售后服務(wù)合同4篇
- 專業(yè)咨詢顧問合作合同(2024年度版)版B版
- 2025年度拆除宴會廳墻體改造項目施工協(xié)議4篇
- 2024陶瓷杯系列新品研發(fā)與市場推廣合作合同3篇
- 2025年度企業(yè)股權(quán)激勵計劃稅務(wù)籌劃與合規(guī)合同3篇
- 2025年新能源電站設(shè)備購銷合同協(xié)議4篇
- 2025年度醫(yī)療中心場地租賃及醫(yī)療設(shè)備租賃補充協(xié)議3篇
- 2025年度醫(yī)療設(shè)備存放租賃合同(2025年度)4篇
- 茶室經(jīng)營方案
- 軍隊文職崗位述職報告
- 小學(xué)數(shù)學(xué)六年級解方程練習(xí)300題及答案
- 電抗器噪聲控制與減振技術(shù)
- 中醫(yī)健康宣教手冊
- 2024年江蘇揚州市高郵市國有企業(yè)招聘筆試參考題庫附帶答案詳解
- 消費醫(yī)療行業(yè)報告
- 品學(xué)課堂新范式
- GB/T 1196-2023重熔用鋁錠
- 運輸行業(yè)員工崗前安全培訓(xùn)
- 公路工程安全風(fēng)險辨識與防控手冊
評論
0/150
提交評論