算法複雜度分為時間複雜度和空間複雜度,二者也是衡量代碼的好壞兩個重要名額:
- 時間複雜度:指執行算法所需要的計算工作量;
- 間複雜度:指執行這個算法所需要的記憶體空間。
算法的複雜性展現在運作該算法時的計算機所需資源的多少上,計算機資源最重要的是時間和空間(即寄存器)資源,是以複雜度分為時間和空間複雜度。
1. 概念了解
1.1 基本執行次數:T(n)
由于運作環境和輸入規模的影響,代碼的絕對執行時間是無法估計的,但我們可以估算出代碼的基本執行次數。
一般情況下,算法中基本操作重複執行的次數是問題規模n的某個函數,用這個函數來表達相對時間,可以記作 T(n)。
1.2 時間複雜度:O(n)
因為執行規則具有不确定性(文章下面就列舉4種可能), 是以T(n) 不足以分析和比較一段代碼的運作時間,就有了漸進時間複雜度(asymptotic time complexity)的概念,官方的定義如下:
若存在函數 f(n),使得當n趨近于無窮大時,T(n)/ f(n)的極限值為不等于零的常數,則稱 f(n)是T(n)的同數量級函數。記作 T(n)= O(f(n)),稱O(f(n)) 為算法的漸進時間複雜度,簡稱:時間複雜度。
漸進時間複雜度用大寫“O”來表示,是以也被稱為大O表示法。
算法時間複雜度裡有O(1), O(n), O(logn), O(nlogn), O(n^2)的概念,這是算法的時空複雜度的表示。
它不僅僅用于表示時間複雜度,也用于表示空間複雜度。
O後面的括号中有一個函數,指明某個算法的耗時/耗空間與資料增長量之間的關系。其中的n代表輸入資料的量。
1.3 空間複雜度:S(n)
與時間複雜度類似,空間複雜度是指算法在計算機内執行時所需存儲空間的度量,記作:S(n)=O(f(n)) 。
上面提到過,O(n)不僅僅用于表示時間複雜度,也用于表示空間複雜度。
2. 場景分析:
這是針對時間複雜度的場景分析,時間複雜度排序為:O(1)< O(log2n)< O(n)< O(n^2)
場景1:T(n) = O(1)
表示算法的運作時間為常量,這是最低的時空複雜度了,也就是耗時/耗空間與輸入資料大小無關,無論輸入資料增大多少倍,耗時/耗空間都不變。
雜湊演算法就是典型的O(1)時間複雜度,無論資料規模多大,都可以在一次計算後找到目标(不考慮沖突的話)。
場景2:T(n) = O(log2n)
當資料增大n倍時,耗時增大log n倍(這裡的log是以2為底的,比如,當資料增大256倍時,耗時隻增大8倍,是比線性還要低的時間複雜度)。
二分查找就是O(log n)的算法,每找一次排除一半的可能,256個資料中查找隻要找8次就可以找到目标。
場景3:T(n) = O(n)
表示該算法是線性算法,資料量增大幾倍,耗時也增大幾倍。
比如常見的for循環周遊,要找到一個數組裡面最大的一個數,你要把n個變量都掃描一遍,操作次數為n,那麼算法複雜度是O(n)。
場景4:T(n) = O(n^2)
代表資料量增大n倍時,耗時增大n的平方倍,這是比線性更高的時間複雜度。
比如冒泡排序,就是典型的O(n^2)的算法,對n個數排序,需要掃描n×n次。
在程式設計的世界中有着各種各樣的算法,除了上述的四個場景,還有許多不同形式的時間複雜度,我們按照時間複雜度,按數量級遞增依次排列為:
常數階 O(1) < 對數階(log2n) < 線性階 O(n)< 線性對數階 O(nlog2n) < 平方階 O(n^2) < 立方階 O(n^3) < k次方階 O(n^k) < 指數階 O(2^n)……
3. 算法比較:
排序算法 | 平均時間 | 最差情形 | 穩定度 | 額外空間 | 備注 |
---|---|---|---|---|---|
冒泡 | O(n 2 ) | O(n 2 ) | 穩定 | O(1) | n 小時較好 |
交換 | O(n 2 ) | O(n 2 ) | 不穩定 | O(1) | n 小時較好 |
選擇 | O(n 2 ) | O(n 2 ) | 不穩定 | O(1) | n 小時較好 |
插入 | O(n 2 ) | O(n 2 ) | 穩定 | O(1) | 大部分已排序時較好 |
基數 | O(log R B) | O(log R B) | 穩定 | O(n) | B 是真數 (0-9) , R 是基數 ( 個十百 ) |
Shell | O(nlogn) | O(n s ) 1<s<2 | 不穩定 | O(1) | s 是所選分組 |
快速 | O(nlogn) | O(n 2 ) | 不穩定 | O(nlogn) | n 大時較好 |
歸并 | O(nlogn) | O(nlogn) | 穩定 | O(1) | n 大時較好 |
堆 | O(nlogn) | O(nlogn) | 不穩定 | O(1) | n 大時較好 |
借鑒了一些官方統計,再加上自己的了解,整理了一篇比較全面的關于介紹時間複雜度的部落格,内容涵蓋了從概念延伸到原理,再到算法的總結,希望對大家有一定的幫助。
少俠請留步 ... ヾ(◍°∇°◍)ノ゙ ...
歡迎點贊、評論、加關注,讓更多人看到學到賺到
更多精彩,請關注我的"今日頭條号":Java雲筆記