1. 程式人生 > >《時間復雜度的計算》

《時間復雜度的計算》

一個 font 推導 n) 等價 foreach 一次循環 大小 div

一:為什麽要計算時間復雜度?

  - 一說起時間復雜度,就和算法扯上了關系,那麽就有了一個問題,在我們寫好了一個算法之後,如何測試這個算法的好或者不好呢?

    - 事後統計法,指的是在算法完成之後,通過實際的運行來檢驗算法的好壞。但是,這樣也有兩個致命的缺點

      - 如果算法不行,那麽我們實際運行圖了個什麽?

      - 機器性能一會好一會不行怎麽破?

    - 因為 事後統計法 的不靠譜,所以我們采用了 事前分析 的方法,也就是我們說的 時間復雜度。

      - 不過因為是事前統計,其算法本身也並沒有通過實際環境的檢驗

      - 所以,時間復雜度,其實只是一個度量

,不是真正的運行時間的投影。

      - 也就是說只是給了你一個尺子去量一下這個算法的耗時,不是這個算法實現以後真的會耗時多少,也不是兩個不同的算法的耗時比例真的可以這麽比。

二:時間復雜度的定義?

  - 語句執行次數 T(n)問題規模 n 的函數

  - 繼而分析 T(n) 隨著 n 的變化並確定 T(n) 的量級

  - 記做 T(n) = O(f(n)), 表示隨著 n 的增大,時間的增長率 和 fn 增長率相同

  - 一般用 O() 表示,也稱 大 (O) 記法

  - 簡單來說,記住這個公式 f(n) = n

三:如何計算算法的時間復雜度?

  - 推導大 O() 計數法

    - 用常數 1 來代替 運行時間的加法常數

    - 在修改後的運行次函數中,只保留最高階

    - 如果最高階存在且不是1,則去除這個項相乘的常數

  - 下面來嘗試如何計算時間復雜度

四:常數階O (1)

  • <?php
        $sum = 0;                    // 執行一次
        $n = 100;                    // 執行一次
        $sum = (1 + n) * n/2;        // 執行一次
        print_r($sum);               // 執行一次

  - 按照定義,這個算法的運行次數是 f(n) = 4,

根據我們的 大 O 推導算法, 第一步就是將 4 變為 1。

  - 在保留最高階時,發現這個算法也沒有最高階,所以這個算法的時間復雜度為 O(1)

  • <?php
        // 如果執行10次呢
        $sum = 0;                    // 執行一次
        $n = 100;                    // 執行一次
        $sum = (1 + n) * n/2;        // 執行一次
        $sum = (1 + n) * n/2;        // 執行一次
        $sum = (1 + n) * n/2;        // 執行一次
        $sum = (1 + n) * n/2;        // 執行一次
        $sum = (1 + n) * n/2;        // 執行一次
        print_r($sum);               // 執行一次

  - 事實上無論 n 為多少,都是時間恒定的算法,也是為常數階 O(1)

五:線性階O (n)

  • <?php
        $n = n;
        foreach ($n as $v) {
            // 時間復雜度為 O(1) 的序列
        }

  - 按照定義,這個算法的運行次數是 f(n) = n, 根據我們的 大 O 推導算法,保存最高階的 1,

  - 也是為線性階 O(n)

六:對數階O (logn)

  • <?php
        $count = 1;
        while ($count < n) {
            $count = $count * 2;
            // 時間復雜度為 O(1) 的序列
       }

  - 由於 count 每次 X2 ,有多少個 2 相乘後,便會退出循環。

  - 由 2x=n 得到 x = log2n

  - 對數階O (logn)

七:平方階O (n2)

  • <?php
        foreach ($n as $v) {
            func($v);
        }
    
        function func () {
            for ($i = 0; $i < n; $i++) {
                // 時間復雜度為 O(1) 的
            }
        }

  - 外層調用了一個循環,循環 n 次去執行 func 函數

  - func 函數內部又執行一次循環輸出

  - 也就是說,這個算法一共執行了 f(n) = n2

  • // 等價於
    <?php
        foreach ($n as $v) {
            for ($i = 0; $i < n; $i++) {
                // 時間復雜度為 O(1) 的
            }
        }

  - 也就是 平方階O (n2)

七:時間復雜度耗時大小排列(越小越好)

  - O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(1) < O(nn)

  - 一般超過 O(n2) 的,時間太長,就不做計算了,也就是說,一個算法,最長耗時不能超過 O(n2)

《時間復雜度的計算》