小前端學算法之複雜度分析

數據結構和算法自己解決的是「快」和「省」的問題,即如何讓代碼運行的更快,如何讓代碼更省儲存空間。 因此複雜度分析是整個算法學習的精髓。算法

大O複雜度表示法

推倒大O階

算法的執行效率,就是算法代碼執行的時間。來估算一下下面代碼的執行時間。數組

function sum(n) {
    let total = 0;
    for (let i=0;i < n;i++) {
        total = total + i
    }
    return total;
}
複製代碼

假設每行代碼執行的時間都同樣,都是unit_time。bash

第 2 行代碼須要 1 個unit_time 的執行時間,第 三、4 行都運行了 n 遍,因此須要 2n*unit_time 的執行時間,因此這段代碼總的執行時間就是 (2n+1)*unit_time。數據結構

能夠看出,代碼的執行時間T(n) 與每行代碼的執行次數成正比數據結構和算法

再來推導下面代碼的運行時間:學習

function sum(n) {
    let total = 0;
    for (let i=1;i<=n;i++) {
        for (let j=1;j<=n;j++) {
            total = total + i * j
        }
    }
    return total
}
複製代碼

一樣第2行須要 1個 unit_time 的執行時間,第3行代碼循環執行了n遍,須要n * unit_time的執行時間,第四、5行執行了n² 遍,因此須要(2n²+n+1)*unit_time 的執行時間。ui

儘管咱們不知道unit_time的具體值,但經過兩段代碼的執行時間推導過程,咱們獲得一個很是重要的規律,那就是,全部代碼的執行時間T(n) 與每行代碼的執行次數n成正比spa

T(n) = O(f(n))
複製代碼

T(n) 表明代碼執行的時間,n表示數據規模的大小;f(n)表示每行代碼執行的次數總和。公式中的O,表示代碼的執行時間T(n) 與f(n) 表達式成正比。code

大O時間複雜度實際上並不具體表示代碼真正的執行時間,而是表示***代碼執行時間隨數據規模增長變化的趨勢***,因此,也叫作漸進時間複雜度。cdn

當n很大時,公式中的低階、常量、係數三部分並不左右增加的趨勢,因此能夠忽略。咱們只須要記錄一個最大量級就能夠了,因此上面兩段代碼就能夠計做:T(n) = O(n) 和 T(n) = O(n²)。

時間複雜度分析方法

  • 只關注循環次數最多的一段代碼
  • 加法法則:總複雜度等於量級最大的那段代碼的複雜度
  • 乘法法則:嵌套代碼的複雜度等於嵌套內外代碼複雜度的乘積

常見的時間複雜度分析

常數階 O(1)

O(1)只是常量級時間複雜度的一種表示方法,並非指只執行了一行代碼,好比下面這段代碼,即便有3行,他的時間複雜度也是O(1),而不是O(3)。

let i = 2;
let j = 5;
let sun = i + j;
複製代碼

通常狀況下,只要算法中不存在循環語句、遞歸語句,即使有成千上萬行代碼,其時間複雜度也是O(1)。

線性階 O(n)

下面這段代碼的時間複雜度爲O(n),由於循環體中的代碼須要執行n次。

let sum = 0;
for (let i=0;i<n;i++){
    sum = sum +i
}
複製代碼

咱們要分析算法的複雜度,關鍵就是要分析循環結構的運行狀況。上面代碼由於循環體中代碼須要執行n次,因此時間複雜度爲O(n)。

對數階 O(logn) O(nlogn)

對數階時間複雜度很是常見。

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

從上面代碼中可用看出,遍歷從1開始,每循環一次就乘以2,當i大於n時循環結束。因爲2的x次方等於n,x = log2n,這個循環的時間複雜度就是O(log2n)。無論是以2爲底,仍是以3爲底,咱們均可以把全部對數階的時間複雜度計做:O(logn)。

平方階 O(n²)
for (let i=0;i<n;i++) {
    for (let j=o;j<n;j++) {
        /*時間複雜度爲O(1)的程序步驟*/
    }
}
複製代碼

根據循環的時間複雜度等於循環體的複雜度乘以該循環運行的次數。因此上面代碼的時間複雜度爲O(n²)。

image

最優算法

通常狀況下,隨着n的增大,T(n) 增加最慢的算法爲最優算法。

最壞狀況

咱們查找一個有n個隨機數字數組中的某個數字,最好的狀況是數組的第一個數字就是,那麼算法的時間複雜度爲O(1),但也可能這個數字在最後一位,那麼算法的時間複雜度就是O(n),這就是最壞狀況了。

最壞狀況運行時間是一種保證,那就是運行時間不會再壞了。一般除非特別指定,咱們提到的運行時間都是最壞狀況的運行時間。

本文摘自極客時間王爭老師的 數據結構與算法之美

摘自《大話數據結構》

相關文章
相關標籤/搜索