偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

怎么計(jì)算我們自己程序的時(shí)間復(fù)雜度

開(kāi)發(fā) 前端
這篇內(nèi)容我們梳理了一下不同的時(shí)間復(fù)雜對(duì)大概對(duì)應(yīng)什么樣的代碼,讓我們能更正確地估算自己寫(xiě)的程序的時(shí)間復(fù)雜度。在寫(xiě)程序時(shí),我們要注意時(shí)間復(fù)雜度增量的問(wèn)題,盡量避免爆炸級(jí)增長(zhǎng)。

知道自己寫(xiě)的程序的時(shí)間復(fù)雜度,有利于我們寫(xiě)出能夠高效運(yùn)行的程序。

程序是由一個(gè)個(gè)函數(shù)組成的,有些簡(jiǎn)單的由幾個(gè)基礎(chǔ)運(yùn)算組成的函數(shù)大家一眼就能看出來(lái)它的時(shí)間復(fù)雜度,但是大部分函數(shù)沒(méi)那么簡(jiǎn)單,只要函數(shù)里面涉及到了循環(huán)、外部函數(shù)調(diào)用甚至遞歸的時(shí)候它的時(shí)間復(fù)雜度就沒(méi)那么容易分析啦。

這篇文章的內(nèi)容,可以幫你快速推導(dǎo)出程序代碼的時(shí)間復(fù)雜度。

要分析程序的時(shí)間復(fù)雜度,首先還是要確定時(shí)間復(fù)雜度的度量標(biāo)準(zhǔn)— —英文文檔里通常會(huì)用 metric 這個(gè)單詞來(lái)表示,這個(gè)標(biāo)準(zhǔn)規(guī)定了在函數(shù)中平鋪展開(kāi)的代碼、循環(huán)中的代碼、有函數(shù)調(diào)用的代碼、以及遞歸調(diào)用的代碼的時(shí)間復(fù)雜度的測(cè)量方式。

Big O Notations

如何計(jì)算程序的時(shí)間復(fù)雜度呢?最常用的度量方式叫做 Big O Notations 翻譯過(guò)來(lái)叫大O標(biāo)記法。

使用大O標(biāo)記法前要先了解它的幾個(gè)要點(diǎn):

  • 相同配置的計(jì)算機(jī)進(jìn)行一次基本運(yùn)算的時(shí)間是一定的,因此我們將程序基本運(yùn)算的執(zhí)行次數(shù)作為時(shí)間復(fù)雜度的衡量標(biāo)準(zhǔn)。
  • 時(shí)間復(fù)雜度是對(duì)運(yùn)行次數(shù)的錯(cuò)略估計(jì),在計(jì)算時(shí)可以只考慮對(duì)運(yùn)行時(shí)間貢獻(xiàn)大的語(yǔ)句而忽略運(yùn)行次數(shù)少的語(yǔ)句。比如 O(3 * n2 + 10n + 10) 會(huì)被統(tǒng)計(jì)成 O(n2)。
  • 比如有些涉及到排序的程序,執(zhí)行時(shí)間往往依賴于程序的輸入,可以分為最好、最壞、平均情況的時(shí)間復(fù)雜度,這種時(shí)候使用大 O 標(biāo)記法時(shí)我們只用關(guān)注最壞的情況,因?yàn)樽顗那闆r對(duì)衡量程序效率的好壞具有實(shí)際意義。

在大O標(biāo)記法中,常見(jiàn)的時(shí)間復(fù)雜度有一下幾類。

  1. 常數(shù)階:常數(shù)階的復(fù)雜度通常用O(1)表示,不是說(shuō)程序只有一行基礎(chǔ)代碼運(yùn)行,它的意思是不管程序的輸入是什么程序都會(huì)運(yùn)行一個(gè)固定數(shù)量的運(yùn)算,這個(gè)數(shù)可以是任何常數(shù)5、100、200都行,重點(diǎn)是他不會(huì)隨輸入的增長(zhǎng)才被統(tǒng)計(jì)稱 O(1)
  2. 多項(xiàng)式階:很多算法的時(shí)間復(fù)雜度是 O(n)、O(n2)、O(n3)這樣的多項(xiàng)式。
  3. 指數(shù)階:指數(shù)階的時(shí)間復(fù)雜度用O(2n) 、 O(nn) 等表示,這種程序運(yùn)行效率極差,是程序員寫(xiě)代碼一定要避開(kāi)的大坑。
  4. 對(duì)數(shù)階:對(duì)數(shù)階的程序運(yùn)行效率較高,通常用O(logn)、 O(n log n) 等表示。

它們的關(guān)系如下:

圖片圖片

從上面的圖我們可以看到,O(1)是最高效最穩(wěn)定的,完全不受輸入數(shù)據(jù)尺寸增長(zhǎng)的影響,指數(shù)階隨著輸入的增加而爆增,而對(duì)數(shù)階則增長(zhǎng)緩慢。

按照時(shí)間復(fù)雜度從低到高排序:

O(1) < O(logn) < O(n) < O(n log n) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

在寫(xiě)程序時(shí),我們要注意時(shí)間復(fù)雜度增量的問(wèn)題,盡量避免爆炸級(jí)增長(zhǎng)。

了解完時(shí)間復(fù)雜度的大O標(biāo)記法后,接下來(lái)我們看下怎么把我們平時(shí)接觸的代碼轉(zhuǎn)化為其對(duì)應(yīng)的時(shí)間復(fù)雜度。

順序語(yǔ)句的復(fù)雜度

這是最簡(jiǎn)單的代碼結(jié)構(gòu),比如說(shuō)我們有一個(gè)下面的計(jì)算3個(gè)數(shù)字的平方和的函數(shù)。

function squareSum(a, b, c) {
  const sa = a * a;
  const sb = b * b;
  const sc = c * c;
  const sum = sa + sb + sc;
  return sum;
}

函數(shù)中的每個(gè)語(yǔ)句都是一個(gè)基本運(yùn)算。每行的時(shí)間復(fù)雜度為 O(1)。我們把所有語(yǔ)句的時(shí)間加起來(lái),它仍然是 O(1), 記住昂,不是O(3)。

O(1)表示程序時(shí)常數(shù)級(jí)的時(shí)間復(fù)雜度,不管程序的輸入是什么程序都會(huì)運(yùn)行數(shù)量固定的操作。

注意如果順序排列的代碼中有對(duì)函數(shù)的調(diào)用,復(fù)雜度就不是O(1)了,你想知道是多少?

條件語(yǔ)句的復(fù)雜度

很少有會(huì)有程序代碼沒(méi)有任何條件語(yǔ)句。因?yàn)榇?O 標(biāo)記法關(guān)注程序運(yùn)行的的最壞情況,所以對(duì)一個(gè)類似這樣的條件語(yǔ)句:

if (isValid) {
  statement1;
  statement2;
} else {
  statement3;
}

它的時(shí)間復(fù)雜度可以按下面這個(gè)公式推導(dǎo)出來(lái):

T(n) = Math.max([t(statement1) + t(statement2)], [time(statement3)])

比如說(shuō)下面這個(gè)代碼:

if (isValid) {
  array.sort();
  return true;
} else {
  return false;
}

if代碼塊中的時(shí)間復(fù)雜度為O( n log n) — 常用編程語(yǔ)言內(nèi)置排序算法的時(shí)間復(fù)雜度,else代碼塊的時(shí)間復(fù)雜度為O(1),那么整個(gè)代碼的時(shí)間復(fù)雜度為:

O([n log n] + [n]) => O(n log n)

循環(huán)語(yǔ)句的復(fù)雜度

線性循環(huán)

for (let i = 0; i < array.length; i++) {
  statement1;
  statement2;
}

對(duì)于這個(gè)例子,循環(huán)執(zhí)行 array.length次,所有與輸入數(shù)據(jù)增長(zhǎng)而成比例增長(zhǎng)的循環(huán)都具有線性—常數(shù)階的時(shí)間復(fù)雜度 O(n)。

對(duì)數(shù)循環(huán)

觀察下面的程序:

function fn(n) {
  i = 1;
  while( i < n) {
     i = i*2;
  }
 }

對(duì)于這個(gè)程序,我們無(wú)法確定while 以及 i = i*2 語(yǔ)句運(yùn)行了多少次,這時(shí)可以假設(shè)運(yùn)行了x次,每次運(yùn)行后i的值為2、22、23… 當(dāng)while 語(yǔ)句的條件不滿足即i = n時(shí)結(jié)束,也就是2x = n , x = log2n ,它的時(shí)間復(fù)雜度近似于O(logn )。

固定次數(shù)循環(huán)

for (let i = 0; i < 4; i++) {
  statement1;
  statement2;
}

針對(duì)固定條件的循環(huán),像上面這個(gè)程序一樣,無(wú)聊時(shí)固定循環(huán)4次還是 100 次時(shí)間復(fù)雜度都是 O(1)。

嵌套循環(huán)

for (let i = 0; i < n; i++) {
  statement1;

  for (let j = 0; j < m; j++) {
    statement2;
    statement3;
  }
}

假設(shè)循環(huán)中的語(yǔ)句都是基礎(chǔ)操作,沒(méi)有對(duì)函數(shù)的調(diào)用,那么這個(gè)代碼有兩層嵌套循環(huán),時(shí)間復(fù)雜度為O(n2)。

循環(huán)中有函數(shù)調(diào)用的時(shí)間復(fù)雜度

假如我們有這樣一個(gè)程序:

for (let i = 0; i < n; i++) {
  fn1();
  for (let j = 0; j < n; j++) {
    fn2();
    for (let k = 0; k < n; k++) {
      fn3();
    }
  }
}

根據(jù) fn1、fn2 和 fn3 函數(shù)自身的時(shí)間復(fù)雜度,整個(gè)程序?qū)碛胁煌倪\(yùn)行時(shí)間。

如果這三個(gè)函數(shù)它們都是常數(shù)階 O(1),那么最終的運(yùn)行時(shí)間將為 O(n3)。但是如果只有 fn1 和 fn2 是常數(shù)介, fn3 的時(shí)間復(fù)雜度為 O(n2),則該程序的運(yùn)行時(shí)間將為 O(n5)。

一般來(lái)說(shuō),循環(huán)中有函數(shù)調(diào)用,時(shí)間復(fù)雜度可以用下面這個(gè)公式計(jì)算:

T(n) = n * [ t(fn1()) + n * [ t(fn2()) + n * [ t(fn3()) ] ] ]

函數(shù)遞歸調(diào)用的時(shí)間復(fù)雜度

function fn(n) {
 if (n == 1 || n == 2) {
   return 1;
 }
 return fn(n - 1) + fn(n - 2);
}

以上是學(xué)算法都學(xué)過(guò)的斐波那切數(shù)列的遞歸調(diào)用實(shí)現(xiàn)版本,它的時(shí)間復(fù)雜度為O(2n) ,所以在平時(shí)寫(xiě)代碼時(shí)在你不確定程序能執(zhí)行多少次的時(shí)候,最好不要輕易使用遞歸調(diào)用。

總結(jié)

這篇內(nèi)容我們梳理了一下不同的時(shí)間復(fù)雜對(duì)大概對(duì)應(yīng)什么樣的代碼,讓我們能更正確地估算自己寫(xiě)的程序的時(shí)間復(fù)雜度。

責(zé)任編輯:武曉燕 來(lái)源: 網(wǎng)管叨bi叨
相關(guān)推薦

2024-04-25 08:33:25

算法時(shí)間復(fù)雜度空間復(fù)雜度

2015-10-13 09:43:43

復(fù)雜度核心

2021-09-17 10:44:50

算法復(fù)雜度空間

2019-11-18 12:41:35

算法Python計(jì)算復(fù)雜性理論

2021-01-05 10:41:42

算法時(shí)間空間

2009-07-09 10:45:16

C#基本概念復(fù)雜度遞歸與接口

2021-10-15 09:43:12

希爾排序復(fù)雜度

2024-04-15 12:48:00

2022-02-22 10:11:01

系統(tǒng)軟件架構(gòu)

2020-12-30 09:20:27

代碼

2014-12-10 09:23:14

2022-02-13 20:04:04

鏈表節(jié)點(diǎn)代碼

2024-04-09 07:53:04

高可用架構(gòu)擴(kuò)展性

2020-11-30 06:26:31

算法時(shí)間表示法

2021-06-28 06:15:14

算法Algorithm時(shí)間空間復(fù)雜度

2020-12-30 05:35:56

數(shù)據(jù)結(jié)構(gòu)算法

2021-04-25 14:29:02

數(shù)據(jù)結(jié)構(gòu)動(dòng)態(tài)數(shù)組時(shí)間復(fù)雜度

2018-12-18 10:11:37

軟件復(fù)雜度軟件系統(tǒng)軟件開(kāi)發(fā)

2019-12-24 09:46:00

Linux設(shè)置密碼

2022-08-16 09:04:23

代碼圈圈復(fù)雜度節(jié)點(diǎn)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)