算法複雜度分爲時間複雜度和空間複雜度,二者也是衡量代碼的好壞兩個重要指標:
- 時間複雜度:指執行算法所需要的計算工作量;
- 間複雜度:指執行這個算法所需要的內存空間。
算法的複雜性體現在運行該算法時的計算機所需資源的多少上,計算機資源最重要的是時間和空間(即寄存器)資源,因此複雜度分爲時間和空間複雜度。
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雲筆記