【小豬佩奇漫畫】| 複雜度分析原來那麼簡單!

一、數據結構是用來幹嗎的?

數據結構與算法的誕生是讓計算機「執行的更快」、「更省空間」的。前端

二、用什麼來評判數據結構與算法的好壞?

從「執行時間」和「佔用空間」兩個方面來評判數據結構與算法的好壞。web

三、什麼是複雜度?

用「時間複雜度」和「空間複雜度」來描述性能問題,二者統稱爲複雜度。算法

四、複雜度描述了什麼?

複雜度描述的是算法執行時間(或佔用空間)與數據規模的增加關係。編程

一、和性能分析相比有什麼優勢?

輔助度分析有不依賴執行環境、成本低、效率高、易操做、指導性強的特色。數組

二、爲何要複雜度分析?

複雜度描述的是算法執行時間(或佔用空間)與數據規模的增加關係。bash

一、什麼方法能夠進行復雜度分析?

方法:「大 O 表示法」數據結構

二、什麼是大 O 表示法?

算法的「執行時間」與每行代碼的「執行次數」成正比【T(n) = O(f(n)) 】=》其中T(n)表示算法執行總時間,f(n)表示每行代碼執行總次數,而n每每表示數據的規模。性能

三、大 O 表示法的特色?

因爲時間複雜度描述的是算法執行時間與數據規模的增加變化趨勢,常量階、低階以及係數實際上對這種增加趨勢不產決定性影響,因此在作時間複雜度分析時忽略這些項。ui

四、複雜度分析法則
  • [單段代碼看頻率]:看代碼片斷中「循環代碼」的時間複雜度。spa

  • [多段代碼看最大]:若是多個 for 循環,看「嵌套循環最多」的那段代碼的時間複雜度。

  • [嵌套代碼求乘積]:循環、遞歸代碼,將內外嵌套代碼求乘積去時間複雜度。

  • [多個規模求加法]: 法有兩個參數控制兩個循環的次數,那麼這時就取兩者複雜度相加。

時間複雜度

一、什麼是複雜度?

全部代碼的「執行時間 T(n)」 與每行代碼的「執行次數n」 成正比【T(n) = O(f(n)) 】。

#####二、分析的三個方法 ■ 最多法則

忽略掉公式中的常量、低階、係數,取最大循環次數就能夠了,也就是循環次數最多的那行代碼。

▍Example

1 // 求n個數字之和
2 int xiaolu(int n) {
3   int sum = 0;
4   for (int i = 1; i <= n; ++i) {
5     sum = sum + i;
6   }
7   return sum;
8 }
複製代碼

▍分析 第二行是一行代碼,也就是常量級別,與 n 沒有關係,能夠忽略,4、五行代碼是咱們重點分析對象,與 n 有關,時間複雜度就是反映執行時間和 n 數據規模的關係。求 n 個數據之和須要執行 n 次。因此時間複雜度爲 O(n)。

■ 加法法則

總複雜度等於循環次數最多的那段複雜度。

▍Example

1 int xiaolu(int n) {
 2   int sum = 0;
 3   //循環一
 4   for (int i = 1; i <= 100; j++) {
 5     sum = sum + i;
 6   }
 7   //循環二
 8   for (int j = 1; j <= n; j++) {
 9      sum = sum + i;
10   }
11 }
複製代碼

▍分析 上邊有兩個循環,一個循環 100 次,另外一個循環 n 次,咱們選擇循環次數最多的那一個且和「數據規模 n 」相關的循環。由上可知,咱們很容易選出循環二,即和數據規模 n 有關,循環次數最多,循環次數最多的那段代碼時間複雜度就表明整體的時間複雜度,爲 O(n) ;

■ 乘法法則

當咱們遇到嵌套的 for 循環的時候,怎麼計算時間複雜度呢?那就是內外循環的乘積。

▍Example

1 for (int j = 1; j <= n; j++) {
2     for(int i = 1; i <= n; i++)
3     sum = sum + i;
4 }
複製代碼

▍分析 外循環一次,內就循環 n 次,那麼外循環 n 次,內就循環 n*n 次。因此時間複雜爲 O(n²)。

空間複雜度

一、什麼是空間複雜度?

表示算法的「存儲空間」與「數據規模」之間的增加關

▍Example

int i = 0;
  int[] a = new int[n];
  for (i; i <n; ++i) {
    a[i] = i * i;
  }
複製代碼

▍分析 在全部代碼中,咱們很容易尋找到存儲空間相關的代碼,就是第二行,申請了一個 n 大小的存儲空間,因此空間複雜度爲 O(n)。

二、最多見的空間複雜度

O(1)、O(n)、O(n²)。

■ O(1)

常量級的時間複雜度表示方法,不管是一行代碼,仍是多行,只要是常量級的就用 O(1) 表示。

▍Example

1 int i = 1;
2 int j = 2;
3 int sum = i + j;
複製代碼

▍分析 由於這三行代碼,也就是常量級別的代碼不隨 n 數據規模的改變而改變。(循環、遞歸除外)

■ O(logn) | O(nlogn)

「對數階時間複雜度」,最難分析的一種時間複雜度。

▍Example

1 i=1;
2 while (i <= n)  {
3   i = i * 3;
4 }
複製代碼

▍分析 要求這段代碼的時間複雜度就求這段代碼執行了多少次,看下圖具體分析。

image.png

▍補充 不論是以 2 爲底、以 3 爲底,仍是以 10 爲底,能夠把全部對數階的時間複雜度都記爲 O(logn),由於對數之間能夠轉換的,參照高中課本。

■ O(m+n) | O(m*n)

參照上邊講到的加法和乘法法則。

一、最好、最壞時間複雜度

所謂的最好、最壞時間複雜度分別對應代碼最好的狀況和最壞的狀況下的執行。

▍Example

1 //在一個 array 數組中查找一個數據 a 是否存在
2for (int i = 1; i < n; i++) {
3    if (array[i] == a) {
4       return i;
5    }
6 }
複製代碼

▍分析 ① 最好狀況就是數組的第一個就是咱們要查找的數據,上邊代碼之執行一遍就能夠,這種狀況下的時間複雜度爲最好時間複雜度,爲 O(1)。

② 最壞的狀況就是數組的最後一個纔是咱們要查找的數據,須要循環遍歷 n 遍數組,也就對應最壞的時間複雜度爲 O(n)

二、平均時間複雜度

平均時間複雜度須要藉助機率論的知識去分析,也就是咱們機率論中所說的加權平均值,也叫作指望值。

▍分析 好比上方的例子,假設咱們查找的數據在數組中的機率爲 1/2;出如今數組中的機率爲 n/1,根據下邊的公式就能夠算出出現的機率爲 1/2n

而後咱們再把每種狀況考慮進去,就能夠計算出平均時間複雜度。

■ 幾種複雜度性能對比

公衆號:一個不甘平凡的碼農

公衆號:一個不甘平凡的碼農

記錄了三本學渣從 0 到 1 的編程故事,是一個致力於原創「數據結構與算法」之美的「web 前端」 技術號。

公衆號回覆 「葵花寶典」 便可領取小鹿收藏的自學資料。

一個專一於數據結構與算法之美的前端號
相關文章
相關標籤/搜索