資料結構與演算法分析——開篇以及複雜度分析

g-sabo發表於2019-11-29

你也許已經發現了,工作了幾年,原以為已經是一隻老鳥。但看到剛參加工作的同事,你發現,原來自己一直在原地踏步。跟新人相比,你的唯一優勢就是對業務更熟悉而已,別的就沒有什麼優勢了。

怎樣才能夠讓自己更上一層樓呢?學習更多的框架?做更多專案?其實,程式設計師真正要做的是修煉內功,也就是夯實基礎。比如設計模式、網路原理,當然也包括接下來要說的資料結構與演算法分析。

  1. 告別爛程式碼,寫出效能更好地程式碼。
  2. 解決問題的思路和方法,程式設計之外也有應用。
  3. 思考能力才是程式設計師的核心競爭力,而演算法能夠有效地鍛鍊這方面。

當然也有其他原因,進大廠、不被淘汰、完成領導對程式碼簡潔度效能的要求。

  1. 邊學邊練,一週用2~3個小時刷題。
  2. 帶著疑問去學習,多想為什麼。
  3. 學習演算法是個需要沉澱的過程,切勿急於求成。

複雜度分析是演算法學習的精髓,幾乎貫穿整個學習過程。掌握了複雜度分析,恭喜你,資料結構與演算法分析的學習已經完成了一半。

  • 時間複雜度

大O時間複雜度實際並不是程式碼的真正執行時間,而是程式碼執行時間隨資料規模增長而呈現的變化趨勢。程式真正執行時間受環境以及資料規模影響很大,例如相同條件下i7處理速度肯定比i5快,i7處理器處理10條資料肯定比10W條塊。
常見的空間複雜度就是 常量階O(1)、線性階O(n)、指數階、對數階O(logn)、線性對數階O(nlogn),指數階。

funtion sum (int n) {   
    int sum = 0;    
    for (int i=1; i <= n; i++) {    
        sum = sum + i;  
    }   
    return sum; 
}
# 第 2 行程式碼執行了一次,第 3 、4各執行了 n 遍。所以時間複雜度為 2n + 1 , 也就是 n 。
  1. 最好時間複雜度
  2. 最壞時間複雜度
  3. 均攤時間複雜度
    funtion find ( int[] array ,  int n ,  int m ) { 
    int position = -1;  
    for (; i < n; ++i) { 
        if (array[i] == m) {       
            position = i;       
            break;  
        }  
    }
    return position;
    }
    #如上程式碼,尋找m在陣列中的位置。如果第一個元素就是 m 時間複雜度就是 1 。如果 m 不在陣列中,時間複雜度就是 n 。這是就用到最好時間複雜度、最壞時間複雜度和平均時間複雜度。
    #最好情況,第一個元素就是m。所以,最好時間複雜度就是 1 。
    #最壞情況,m 不在陣列中。所以,最好時間複雜度就是 n 。
    #均攤時間複雜度,此時共有 n + 1 可能性。每種情況累加後再除 n + 1,就是均攤時間複雜度。( 1 + 2 + 3 ..... n + n ) / ( n + 1 ) = n ( n + 3 ) / 2 ( n + 1 ) ,簡化後就是 n 。
  • 空間複雜度

空間複雜度表示的是儲存空間與資料規模之間的增長關係。

funtion getArray ( int n) {
    int i = 0;  
    int[] a = new int[n];
    for (  ; i <n; ++i) {  
        a[i] = i;  
    }
    return a;
}
#第 2 行程式碼申請了變數 a ,別處就沒有再申請儲存了。所以,空間複雜度就是 n 。

今日筆記主要內容是時間複雜度,只列舉了簡單的例子。

網上有很多題,建議大家去做下,熟能生巧是很有道理的。

以上內容,如有錯誤點或改進點,希望大家能夠指出。有什麼問題,也可以留言,大家一起討論、學習,一起進步。

相關文章