算法的時間複雜度

算法的時間複雜度

時間複雜度:咱們將算法執行運算的操做數丟棄掉低階項,再去掉全部的係數.java

在它前面加上一個O,就是大O表示法.算法

int n = 100;
int a = 10;
System.out.println(a);
//總共執行3次
複製代碼

沒有更低階的項了,係數是3, 去掉係數3, 因此時間複雜度是 O(1)數組

int n = 100;
        int a = 10; 
        for (int i = 0; i < n; i++) {  //n次
            System.out.println(a);     //n次
        }
        System.out.println(a);
        //總共執行2n + 3次
複製代碼

去掉低階項3,再去掉係數2,因此它的時間複雜度就是O(n)markdown

int n = 100;
        int a = 10;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.println(a);
                System.out.println(a);
            }
        }
        System.out.println(a);
//2n^2+3次
複製代碼

去掉低階項3,再去掉係數2, 因此它的時間複雜度是O(n2)數據結構

常見的時間複雜度

image-20200622213828555

即便係數很大,可是對於咱們來講都沒有意義,只要n的數量級夠大,總能抹平低階項和係數帶來的影響 , 高階項纔是函數增加的主要影響因素.函數

增加速度

image-20200622214111780

通常法則

for循環

假設循環體的時間複雜度爲O(n),循環次數爲m,則這個循環的時間複雜度爲O(m*n).spa

image-20200622214712730

時間複雜度爲O(n*1), 即O(n).指針

嵌套的for循環

對於多個循環,假設循環體的時間複雜度爲O(n),各個循環的循環次數分別爲a,b,c,則這個循環的時間複雜度爲O(n*a*b*c...).code

分析的時候應該從裏向外分析這些循環.orm

image-20200622214955082

時間複雜度爲O(1*m*n), 即O(m*n)

順序語句

各個語句的運行時間求和便可(或者說取最大值).

image-20200622215245744

時間複雜度爲O(2+n+n2+1),即爲 O(n2).

分支語句

總的時間複雜度等於其中時間複雜度最大的路徑的時間複雜度

image-20200622215630523

這裏若是運氣好,第一次判斷進入if就結束了,那麼時間複雜度就是O(n),

可是算法的時間複雜度是按最壞的狀況來算的,因此看時間複雜度最大的路徑是怎樣的,這纔是最終的時間複雜度.

因此上圖的時間複雜度爲O(n2)

函數調用

for (int i = 0; i < n; i++) {  //O(n)
             list.insert(0,i);   //O(n)
     }
複製代碼

上面的insert語句的時間複雜度是O(n), 而不是O(1), 因此它的時間複雜度是O(n2).

函數調用要看函數體裏面的時間複雜度.

注意:

  • 算法的速度並不能簡單的以執行時間做爲衡量標準

大O表示法

<<算法導論>>裏的定義:

對於給定的函數g(n) , 用O(g(n))來表示如下函數的集合:

O(g(n)) = {f(n) : 存在正常量c和n0 , 使得對全部n>=n0 , 有0<=f(n)<=cg(n)}.

咱們使用O記號來給出函數的一個在常量因子內的上界.

大O表示法每每是表示最壞複雜度的.

常見排序算法及其對應的時間複雜度和空間複雜度

img

常見數據結構時間複雜度

image-20200623103802916

查找

  • 數組能夠直接根據下標查詢,因此是O(1)
  • 鏈表必須一個一個的去找,因此是O(n)

頭部插入/刪除

  • 數組須要把每一個數據都向後移動,因此是O(n)
  • 鏈表隨意找一個位置放置元素,指針指向下一個便可,因此是O(1)

尾部插入/刪除

  • 數組直接定位到尾部,輸入數據就能夠(數組未滿纔可插入)
  • 鏈表須要先遍歷才能找到最後一個元素的位置,再進行插入

中間插入/刪除

  • 數組的時間用在了數據的拷貝,覆蓋上面

  • 鏈表的時間用在了遍歷上面

數組和鏈表的選擇

插入/刪除不多,查詢很是多,又不會 Out of memory ,採用數組.

若是是頻繁的插入,遍歷,查詢檢索不多,就採用鏈表.

相關文章
相關標籤/搜索