天天看點

了解算法中的時間複雜度,O(1),O(n),O(log2n),O(n^2)

算法複雜度分為時間複雜度和空間複雜度,二者也是衡量代碼的好壞兩個重要名額:

  • 時間複雜度:指執行算法所需要的計算工作量;
  • 間複雜度:指執行這個算法所需要的記憶體空間。

算法的複雜性展現在運作該算法時的計算機所需資源的多少上,計算機資源最重要的是時間和空間(即寄存器)資源,是以複雜度分為時間和空間複雜度。

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)時間複雜度,無論資料規模多大,都可以在一次計算後找到目标(不考慮沖突的話)。

了解算法中的時間複雜度,O(1),O(n),O(log2n),O(n^2)

場景2:T(n) =  O(log2n)

當資料增大n倍時,耗時增大log n倍(這裡的log是以2為底的,比如,當資料增大256倍時,耗時隻增大8倍,是比線性還要低的時間複雜度)。

二分查找就是O(log n)的算法,每找一次排除一半的可能,256個資料中查找隻要找8次就可以找到目标。

了解算法中的時間複雜度,O(1),O(n),O(log2n),O(n^2)

場景3:T(n) =  O(n)

表示該算法是線性算法,資料量增大幾倍,耗時也增大幾倍。

比如常見的for循環周遊,要找到一個數組裡面最大的一個數,你要把n個變量都掃描一遍,操作次數為n,那麼算法複雜度是O(n)。

了解算法中的時間複雜度,O(1),O(n),O(log2n),O(n^2)

場景4:T(n) =  O(n^2)

代表資料量增大n倍時,耗時增大n的平方倍,這是比線性更高的時間複雜度。

比如冒泡排序,就是典型的O(n^2)的算法,對n個數排序,需要掃描n×n次。

了解算法中的時間複雜度,O(1),O(n),O(log2n),O(n^2)

在程式設計的世界中有着各種各樣的算法,除了上述的四個場景,還有許多不同形式的時間複雜度,我們按照時間複雜度,按數量級遞增依次排列為:

常數階 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雲筆記

繼續閱讀