算法的復(fù)雜度分析

如果想要分析一個(gè)程序的性能巢音,你可以嘗試將程序運(yùn)行,然后收集它的運(yùn)行數(shù)據(jù)尽超,就可以得到程序運(yùn)行所需要的時(shí)間和內(nèi)存官撼。我們將這種分析方法稱為事后統(tǒng)計(jì)法。
事后統(tǒng)計(jì)法是非常樸素的分析方法似谁,但是也兩點(diǎn)問題:

  1. 程序的運(yùn)行需要依賴硬件環(huán)境傲绣,比如同一個(gè)程序在兩臺(tái)性能不一的電腦上的表現(xiàn)是不同的。
  2. 程序運(yùn)行時(shí)間往往收到數(shù)據(jù)規(guī)模的影響秃诵,例如在排序算法中菠净,快排是最優(yōu)秀的算法,如果只使用幾個(gè)數(shù)據(jù)進(jìn)行排序攀唯,可能它的表現(xiàn)還不如冒泡排序革答,但是當(dāng)使用上萬個(gè)數(shù)據(jù)進(jìn)行排序的時(shí)候,他們的性能差異就會(huì)顯現(xiàn)碟嘴。(這種差異可能不是十倍娜扇,而是百倍千倍)

由于這些問題雀瓢,我們一般使用復(fù)雜度分析的方法分析一個(gè)算法的性能,這就是大O復(fù)雜度表示法

大O復(fù)雜度表示法:

大O時(shí)間復(fù)雜度表示法:

拋去計(jì)算機(jī)底層的影響泊业,我們可以使用大O時(shí)間復(fù)雜度表示法來表示代碼執(zhí)行時(shí)間隨數(shù)據(jù)規(guī)模增長的變化趨勢(shì)吁伺,簡(jiǎn)稱時(shí)間復(fù)雜度捆愁。
分析時(shí)間復(fù)雜度有三個(gè)比較使用的方法:

1.只關(guān)注循環(huán)執(zhí)行次數(shù)最多的一段代碼:

敲黑板:循環(huán) 和 最多
下面有一段代碼:

int cal(int n) {
   int sum = 0;
   int i = 1;
   for (; i <= n; ++i) {
     sum = sum + i;
   }
   return sum;
 }

上面的代碼中牙瓢,2憔足、3行代碼都是常量級(jí)的執(zhí)行時(shí)間,和n無關(guān)弓候,在復(fù)雜度分析中可以忽略邦蜜。循環(huán)執(zhí)行次數(shù)最多代碼是 for 循環(huán)中的代碼贱迟,它被執(zhí)行了 n 次,所以總的時(shí)間復(fù)雜度是O(n)

2.加法法則:總復(fù)雜度等于量級(jí)最大的那段代碼的復(fù)雜度:

看下面的代碼:

int cal(int n) {
   int sum_1 = 0;
   int p = 1;
   for (; p < 100; ++p) {
     sum_1 = sum_1 + p;
   }

   int sum_2 = 0;
   int q = 1;
   for (; q < n; ++q) {
     sum_2 = sum_2 + q;
   }
 
   int sum_3 = 0;
   int i = 1;
   int j = 1;
   for (; i <= n; ++i) {
     j = 1; 
     for (; j <= n; ++j) {
       sum_3 = sum_3 +  i * j;
     }
   }
 
   return sum_1 + sum_2 + sum_3;
 }

上面的代碼中缚俏,sum_2部分的代碼的復(fù)雜度為O(n)胀屿,sum_3代碼的復(fù)雜度為O(n2)宿崭,根據(jù)加法法則,cal函數(shù)的復(fù)雜度為O(n2)

3.乘法法則:嵌套代碼的復(fù)雜度等于嵌套內(nèi)外代碼的復(fù)雜度的乘積:

看下面的代碼:


int cal(int n) {
   int ret = 0; 
   int i = 1;
   for (; i < n; ++i) {
     ret = ret + f(i);
   } 
 } 
 
 int f(int n) {
  int sum = 0;
  int i = 1;
  for (; i < n; ++i) {
    sum = sum + i;
  } 
  return sum;
 }

可以看到讹堤,在 cal 的 for 循環(huán)中嵌套了 f 函數(shù)。第一部分的 for 循環(huán)貢獻(xiàn)了 n 的復(fù)雜度梗醇,而 f 函數(shù)也貢獻(xiàn)了 n 的復(fù)雜度,根據(jù)乘法法則手负,cal的復(fù)雜度為 O(n2)竟终。

大O空間復(fù)雜度表示法:

空間復(fù)雜度的定義和時(shí)間復(fù)雜度類似:表示算法需要的存儲(chǔ)空間與數(shù)據(jù)規(guī)模之間的增長關(guān)系。
你只需要分析在算法中申請(qǐng)的存儲(chǔ)空間即可,常見的空間復(fù)雜度有:O(1),O(n),O(n2)

最好镰惦、最壞、平均茵瘾、均攤 時(shí)間復(fù)雜度

同一個(gè)算法在給定不同數(shù)據(jù)的情況下性能可能會(huì)出現(xiàn)很大的差異圣絮,例如:如果一個(gè)數(shù)組已經(jīng)基本有序,那么使用快速排序則有O(n2)的時(shí)間復(fù)雜度棒搜,而最好的情況下復(fù)雜度為O(nlogn)。
基于上面的情況末盔,我們引入了各種復(fù)雜度的度量:

  • 最好情況時(shí)間復(fù)雜度:在最理想的情況下,執(zhí)行這段代碼的時(shí)間復(fù)雜度
  • 最壞情況時(shí)間復(fù)雜度:在最糟糕的情況下游盲,執(zhí)行這段代碼的時(shí)間復(fù)雜度
  • 平均時(shí)間復(fù)雜度:根據(jù)概率論的理論,平均時(shí)間復(fù)雜度的值為代碼執(zhí)行的加權(quán)平均值莺奔,也就是它的期望值。所以你也可以將之稱為加權(quán)平均時(shí)間復(fù)雜度屏富。
  • 均攤時(shí)間復(fù)雜度:你可以將其理解為一種特殊的平均時(shí)間復(fù)雜度:
    先來看下面一段代碼:
 // array表示一個(gè)長度為n的數(shù)組
 // 代碼中的array.length就等于n
 int[] array = new int[n];
 int count = 0;
 
 void insert(int val) {
    if (count == array.length) {
       int sum = 0;
       for (int i = 0; i < array.length; ++i) {
          sum = sum + array[i];
       }
       array[0] = sum;
       count = 1;
    }

    array[count] = val;
    ++count;
 }

你會(huì)發(fā)現(xiàn),如果我們一直使用insert函數(shù)向數(shù)組array中添加數(shù)據(jù)已维,在沒有到達(dá)n垛耳,只需要O(1)的時(shí)間復(fù)雜度,但是如果放入第n個(gè)數(shù)據(jù)泡嘴,復(fù)雜度就會(huì)變?yōu)镺(n),這就出現(xiàn)了在執(zhí)行過程中操作的復(fù)雜度不同的情況,針對(duì)這種情況建椰,我摘取了下面一段話:

對(duì)一個(gè)數(shù)據(jù)結(jié)構(gòu)進(jìn)行一組連續(xù)操作中棉姐,大部分情況下時(shí)間復(fù)雜度都很低夏志,只有個(gè)別情況下時(shí)間復(fù)雜度比較高湿诊,而且這些操作之間存在前后連貫的時(shí)序關(guān)系,這個(gè)時(shí)候,我們就可以將這一組操作放在一塊兒分析宣蠕,看是否能將較高時(shí)間復(fù)雜度那次操作的耗時(shí),平攤到其他那些時(shí)間復(fù)雜度比較低的操作上唱逢。而且,在能夠應(yīng)用均攤時(shí)間復(fù)雜度分析的場(chǎng)合,一般均攤時(shí)間復(fù)雜度就等于最好情況時(shí)間復(fù)雜度叠艳。

注意:只有在最好、最壞徐勃、平均時(shí)間復(fù)雜度在量級(jí)上存在差異的時(shí)候扎酷,區(qū)分它們才有意義谁榜。

以上就是對(duì)算法的復(fù)雜度分析的全部內(nèi)容。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绣张,隨后出現(xiàn)的幾起案子侥涵,更是在濱河造成了極大的恐慌磨总,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厕诡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡寿羞,警方通過查閱死者的電腦和手機(jī)辨泳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來键袱,“玉大人杠纵,你說我怎么就攤上這事倘屹∨男常” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵砍濒,是天一觀的道長樊卓。 經(jīng)常有香客問我七扰,道長,這世上最難降的妖魔是什么轧钓? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任而柑,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘妙同。我一直安慰自己弄抬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布速警。 她就那樣靜靜地躺著忙灼,像睡著了一般酸舍。 火紅的嫁衣襯著肌膚如雪淮阐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天缴饭,我揣著相機(jī)與錄音丢氢,去河邊找鬼比驻。 笑死掸掸,一個(gè)胖子當(dāng)著我的面吹牛悯周,可吹牛的內(nèi)容都是我干的屠橄。 我是一名探鬼主播锐墙,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蚀乔!你這毒婦竟也來了婉弹?” 一聲冷哼從身側(cè)響起马胧,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤威彰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后慨代,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體说莫,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡懂牧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年侈净,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片僧凤。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡畜侦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出躯保,到底是詐尸還是另有隱情旋膳,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布途事,位于F島的核電站验懊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏尸变。R本人自食惡果不足惜义图,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望召烂。 院中可真熱鬧碱工,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至廊谓,卻和暖如春梳猪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蹂析。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工舔示, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人电抚。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓惕稻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蝙叛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子俺祠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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

  • 本文是對(duì)極客時(shí)間《數(shù)據(jù)結(jié)構(gòu)與算法之美》03-04 節(jié)課關(guān)于算法復(fù)雜度分析的小結(jié)。 前面:為什么要學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法...
    柳年思水閱讀 809評(píng)論 0 0
  • 一:什么是復(fù)雜度分析? 1.數(shù)據(jù)結(jié)構(gòu)和算法解決是“如何讓計(jì)算機(jī)更快時(shí)間借帘、更省空間的解決問題”蜘渣。 2.因此需從執(zhí)行時(shí)...
    我是碼神閱讀 434評(píng)論 0 0
  • 總結(jié) 一际起、什么是復(fù)雜度分析拾碌?1.數(shù)據(jù)結(jié)構(gòu)和算法解決是“如何讓計(jì)算機(jī)更快時(shí)間、更省空間的解決問題”街望。2.因此需從執(zhí)行...
    GhostintheCode閱讀 1,801評(píng)論 0 8
  • 順序查找 說明:順序查找適合于存儲(chǔ)結(jié)構(gòu)為順序存儲(chǔ)或鏈接存儲(chǔ)的線性表校翔。 基本思想:順序查找也稱為線形查找,屬于無序查...
    沙海tao金閱讀 2,763評(píng)論 0 0
  • 帝都 一個(gè)夏日 遇見他的文字 第一次有人懂得灾前,其實(shí)你渴望風(fēng)流防症,我無聲了。 第一次有人謬贊說哎甲,其實(shí)你并不笨蔫敲,我想怎么...
    LIEYUWUJI閱讀 352評(píng)論 0 0