<<大話數(shù)據(jù)結(jié)構(gòu)>>之時(shí)間復(fù)雜度

程序猿可以讓步瘾境,卻不可以退縮,可以羞澀陪每,卻不可以軟弱影晓,總之,程序員必須是勇敢的檩禾。
大話數(shù)據(jù)結(jié)構(gòu)


時(shí)間復(fù)雜度序言


當(dāng)前兩天我寫(xiě)完<<大話數(shù)據(jù)結(jié)構(gòu)>>的序言的時(shí)候,我就在想,我該如何把從大話數(shù)據(jù)結(jié)構(gòu)中對(duì)應(yīng)用開(kāi)發(fā)人員有用的知識(shí)提煉出來(lái)?我是該如同課本一樣把所有的知識(shí)羅列個(gè)遍?還是如何如何,我想如果我把所有的東西都羅列出來(lái),那還不如讓廣大的讀者去自己看這本書(shū)呢,畢竟我這小渣渣的層次面還跟不上程杰大神呢,幽默度更不用說(shuō)了,所以我想了幾天 決定把對(duì)開(kāi)發(fā)人員有用的整理出來(lái),其實(shí)也是為了自己以后能夠快速地找到我想要的知識(shí)點(diǎn).利人利己的事情,何樂(lè)而不為呢?


時(shí)間復(fù)雜度的概念以及實(shí)際作用


計(jì)算機(jī)科學(xué)中挂签,算法的時(shí)間復(fù)雜度是一個(gè)函數(shù),它定量描述了該算法的運(yùn)行時(shí)間盼产。這是一個(gè)關(guān)于代表算法輸入值的字符串的長(zhǎng)度的函數(shù)饵婆。時(shí)間復(fù)雜度常用大O符號(hào)表述,不包括這個(gè)函數(shù)的低階項(xiàng)和首項(xiàng)系數(shù)戏售。使用這種方式時(shí)侨核,時(shí)間復(fù)雜度可被稱(chēng)為是漸近的,它考察當(dāng)輸入值大小趨近無(wú)窮時(shí)的情況灌灾。

說(shuō)白了,就是對(duì)函數(shù)或者方法的復(fù)雜程度的度量.那么我們什么時(shí)候使用這個(gè)時(shí)間復(fù)雜度呢?在實(shí)際中,我們或多或少都要寫(xiě)一些方法或者函數(shù),但是如果函數(shù)的時(shí)間復(fù)雜度過(guò)大,就會(huì)影響到整個(gè)項(xiàng)目或者工程的運(yùn)行,耗損不必要的內(nèi)存空間,影響用戶的體驗(yàn)效果,一旦用戶的體驗(yàn)效果不好,那么就是老一套了,該需求,改需求再改需求...但是我們需要改動(dòng)那一些函數(shù)或者方法呢?這就需要到我們的"時(shí)間復(fù)雜度"相關(guān)的知識(shí)了.(當(dāng)然了,空間復(fù)雜度也是需要的,但是我還沒(méi)看到那,所以,見(jiàn)諒~)


算法時(shí)間復(fù)雜度的定義


定義:在進(jìn)行算法分析時(shí)候,語(yǔ)句總的執(zhí)行次數(shù)T(n)是關(guān)于問(wèn)題規(guī)模n的函數(shù),進(jìn)而分型T(n)隨著n的變化情況并確定T(n)的數(shù)量級(jí).算法的時(shí)間復(fù)雜度,也就是算法的時(shí)間度量記作:T(n)=O(f(n)).它表示隨著問(wèn)題規(guī)模n的增大,算法執(zhí)行時(shí)間的增長(zhǎng)率和f(n)的增長(zhǎng)率相同,稱(chēng)作算法的漸近時(shí)間復(fù)雜度,簡(jiǎn)稱(chēng)時(shí)間復(fù)雜度.其中f(n)是問(wèn)題規(guī)模n的某個(gè)函數(shù).

這里用大寫(xiě)的O( )來(lái)體現(xiàn)算法時(shí)間復(fù)雜度的記法,我們稱(chēng)之為大O記法.


分析一個(gè)函數(shù)或者算法的時(shí)間復(fù)雜度


分析一個(gè)函數(shù)或者算法的時(shí)間復(fù)雜度,其實(shí)就是 推導(dǎo)大O階

推導(dǎo)大O階:
1.用常熟1取代運(yùn)行時(shí)間中的所有加法常數(shù).
2.在修改后的運(yùn)行次數(shù)函數(shù)中,只保留最高階項(xiàng).
3.如果最高階項(xiàng)存在且不是1,則去除與這個(gè)像相乘的常數(shù).
得到的結(jié)果就是大O階.

正如書(shū)中所講的一樣,這就是游戲攻略,我們拿著這個(gè)游戲攻略開(kāi)始戰(zhàn)斗吧.


比較常見(jiàn)的大O階分析


    1. 常數(shù)階
      我們來(lái)看下面的這個(gè)算法,作為程序員的我們可能看一眼就知道它是一個(gè)順序結(jié)構(gòu),并且執(zhí)行了三次.那么它的時(shí)間復(fù)雜度是不是就是常數(shù)3呢?因?yàn)閳?zhí)行了三次呀,這可是大錯(cuò)特錯(cuò)了.
      我們來(lái)看推導(dǎo)大O階的方法,首先運(yùn)行次數(shù)是3,我們根據(jù)游戲攻略的第一步,就是要把常數(shù)項(xiàng)3改成1,再根據(jù)第二步和第三步,保留最高項(xiàng),發(fā)現(xiàn)根本沒(méi)有最高項(xiàng),所以這個(gè)算法的時(shí)間復(fù)雜度為O(1).當(dāng)然了,只有順序結(jié)構(gòu)的時(shí)候,不管你執(zhí)行多少次,時(shí)間復(fù)雜度統(tǒng)統(tǒng)是O(1),也就是常數(shù)階.當(dāng)然了,分支結(jié)構(gòu)也是一樣的不管條件是真或者假,你都會(huì)發(fā)現(xiàn)整個(gè)分支結(jié)構(gòu)只是執(zhí)行了一次,所以,跟順序結(jié)構(gòu)大同小異,時(shí)間復(fù)雜度也是O(1).

順序結(jié)構(gòu)

    //順序結(jié)構(gòu)
    int sum =0, n= 100;//執(zhí)行一次
    
    sum = (1+n)/2;//執(zhí)行一次
    
    NSLog(@"%d",sum);//執(zhí)行一次

分支結(jié)構(gòu)

    //分支結(jié)構(gòu)
    
    //整個(gè)分支結(jié)構(gòu)不管條件如何都只執(zhí)行一次
    if (/* DISABLES CODE */ (1) != 2) {
        
        NSLog(@"1真的不等于2幺~");//執(zhí)行一次
        
    }else{
    
        NSLog(@"1等于2");//執(zhí)行一次
    
    }

    1. 線性階
      下面這是一個(gè)for循環(huán),那么它的時(shí)間復(fù)雜度又是多少呢?首先循環(huán)體就是一個(gè)執(zhí)行一次的循環(huán)體,總共執(zhí)行了n次,那么執(zhí)行次數(shù)就是f(n) =n,啟動(dòng)我們的游戲攻略三部曲知道,時(shí)間復(fù)雜度就是為O(n).具體的步驟就不詳細(xì)說(shuō)了,因?yàn)樘?jiǎn)單了不是?

for循環(huán)結(jié)構(gòu)

    for (int i = 0; i< n; i++) {
        
        NSLog(@"執(zhí)行一次");//執(zhí)行一次
        
    }
  • 3.對(duì)數(shù)階
    來(lái)來(lái)來(lái),接著看這個(gè)while循環(huán)結(jié)構(gòu),我們不難發(fā)現(xiàn),當(dāng)count大于n的時(shí)候,循環(huán)體就會(huì)結(jié)束,循環(huán)體中count不斷的乘以2,那么執(zhí)行次數(shù)是多少呢? 2^x = n 可得到 x = log2n;所以根據(jù)游戲攻略我們可以知道這個(gè)while循環(huán)體的時(shí)間復(fù)雜度是 O(log n);感覺(jué)自己看到這都能困了,嘿嘿,懵了,這里要著重看一下.

while循環(huán)結(jié)構(gòu)

    int count = 1;
    
    while (count < n) {
         
        count = count * 2;//執(zhí)行一次
        
    }

  • 4.平方階

實(shí)際應(yīng)用中肯定不能像上面那么只有單個(gè)結(jié)構(gòu),可能有兩種或者兩種以上的結(jié)構(gòu),下面看一下兩個(gè)for循環(huán)嵌套的時(shí)間復(fù)雜度又是如何呢? 我們先看一個(gè)特殊的嵌套,下面的這個(gè)嵌套是兩層都進(jìn)行n次循環(huán),那么總的執(zhí)行次數(shù)函數(shù)就是 f(n) = n^2;接著再根據(jù)我們的游戲攻略一頓計(jì)算,知道我們的時(shí)間復(fù)雜度是 O(n^2 );

兩層都執(zhí)行n次的for循環(huán)

    for (int i = 0; i< n; i++) {
        
        for (int  j = 0; j< n; i++) {
            
            NSLog(@"這個(gè)地方是時(shí)間復(fù)雜度為O(1)的算法");
            
        }
        
    }

如果是下面的這種呢?外層循環(huán)n次,內(nèi)層循環(huán)m次,我們又該如何求解復(fù)雜度呢?其實(shí)跟上面是大同小異的,我們只需要把上面的其中一個(gè)n換成m就好了,所以時(shí)間復(fù)雜度為O(m*n );

    for (int i = 0; i< n; i++) {
        
        for (int j = 0; j< m; i++) {
            
            NSLog(@"這個(gè)地方是時(shí)間復(fù)雜度為O(1)的算法");
            
        }
        
    }
    

那么,再看一下下面的這個(gè)嵌套,我們分析一下它總共執(zhí)行幾次,由于當(dāng)i = 0時(shí),內(nèi)循環(huán)執(zhí)行n此,當(dāng)n = 1時(shí), 執(zhí)行了 n - 1 次, ...當(dāng) i = n-1 時(shí), 執(zhí)行了1次,所以總的執(zhí)行次數(shù)為:

</b>

n + (n -1) +( n -2 ) +.... +1 = n(n +1)/2 = n^2/2 + n/2

根據(jù)我們的游戲秘籍的三部曲,我們可以分析出來(lái),時(shí)間復(fù)雜度為 O( n^2 );

    for (int i = 0; i< n; i++) {
        
        for (int j = i; j< n; j++) {
            
            NSLog(@"這個(gè)地方是時(shí)間復(fù)雜度為O(1)的算法");
            
        }
        
    }
  • 5.函數(shù)的調(diào)用
    我們看一下 如何我們調(diào)用函數(shù)或者方法,那么該如何計(jì)算時(shí)間復(fù)雜度呢?這里我調(diào)用OC中的方法,然后就是下面的這個(gè),其實(shí)我們只要用嵌套的眼光看待就行,根據(jù)我們的游戲秘籍 不難得到下面的這個(gè)時(shí)間復(fù)雜度是 O (n ^2);如果函數(shù)或者方法中有其他的按照嵌套的規(guī)律來(lái)計(jì)算時(shí)間復(fù)雜度就好;額
    for (int i = 0; i< n; i++) {
        
        for (int j = 0; j< n; j++) {
            

            [self function];
        }
        
    }
    


-(void)function{

    NSLog(@"這個(gè)地方是時(shí)間復(fù)雜度為O(1)的算法");

}


常見(jiàn)的時(shí)間復(fù)雜度


我就直接上圖了,主要是比較集中常見(jiàn)的時(shí)間復(fù)雜度的大小.


幾種時(shí)間復(fù)雜度的大小.png


時(shí)間復(fù)雜度總結(jié) :時(shí)間復(fù)雜度對(duì)我們開(kāi)發(fā)過(guò)程中做算法以及項(xiàng)目的優(yōu)化有著極大的幫助.雖然我們作為的是一個(gè)開(kāi)發(fā)人員,不是一個(gè)科研人員,但是,我們了解時(shí)間復(fù)雜度的概念和作用是有著很大的優(yōu)勢(shì)的,時(shí)間復(fù)雜度主要就是掌握游戲攻略三部曲就好了.文筆不好如果有什么問(wèn)題或者意見(jiàn),歡迎評(píng)論.謝謝.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搓译,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锋喜,更是在濱河造成了極大的恐慌些己,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘿般,死亡現(xiàn)場(chǎng)離奇詭異段标,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)炉奴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)逼庞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人盆佣,你說(shuō)我怎么就攤上這事往堡⌒岛桑” “怎么了共耍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵虑灰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我痹兜,道長(zhǎng)穆咐,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任字旭,我火速辦了婚禮对湃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘遗淳。我一直安慰自己拍柒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布屈暗。 她就那樣靜靜地躺著拆讯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪养叛。 梳的紋絲不亂的頭發(fā)上种呐,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音弃甥,去河邊找鬼爽室。 笑死,一個(gè)胖子當(dāng)著我的面吹牛淆攻,可吹牛的內(nèi)容都是我干的阔墩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瓶珊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼啸箫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起艰毒,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤筐高,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后丑瞧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體柑土,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年绊汹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稽屏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡西乖,死狀恐怖狐榔,靈堂內(nèi)的尸體忽然破棺而出坛增,到底是詐尸還是另有隱情,我是刑警寧澤薄腻,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布收捣,位于F島的核電站,受9級(jí)特大地震影響庵楷,放射性物質(zhì)發(fā)生泄漏罢艾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一尽纽、第九天 我趴在偏房一處隱蔽的房頂上張望咐蚯。 院中可真熱鬧,春花似錦弄贿、人聲如沸春锋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)期奔。三九已至,卻和暖如春直奋,著一層夾襖步出監(jiān)牢的瞬間能庆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工脚线, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搁胆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓邮绿,卻偏偏與公主長(zhǎng)得像渠旁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子船逮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容