一、說明
時間複雜度和空間複雜度是用來評價演算法效率高低的2個標準,身為開發者肯定會經常會聽到這2個概念,但它們分別是什麼意思呢?
其實這兩個概念從字面意思上也能看出一二:
時間複雜度:就是說執行演算法需要消耗的時間長短,越快越好。比如你在電腦上開啟計算器,如果乙個普通的運算要消耗1分鐘時間,那誰還會用它呢,還不如自己口算呢。
空間複雜度:就是說執行當前演算法需要消耗的儲存空間大小,也是越少越好。本來計算機的儲存資源就是有限的,如果你的演算法總是需要耗費很大的儲存空間,這樣也會給機器帶來很大的負擔。
二、時間複雜度的計算
表示方法
我們一般用「大o符號表示法」來表示時間複雜度:t(n) = o(f(n))
n是影響複雜度變化的因子,f(n)是複雜度具體的演算法。
常見的時間複雜度量級
常數階o(1)
線性階o(n)
對數階o(logn)
線性對數階o(nlogn)
平方階o(n²)
立方階o(n³)
k次方階o(n^k)
指數階(2^n)
接下來再看一下不同的複雜度所對應的演算法型別。
常數階o(1)
int a =1;
int b =2;
int c =
3;
我們假定每執行一行**所需要消耗的時間為1個時間單位,那麼以上3行**就消耗了3個時間單位。那是不是這段**的時間複雜度表示為o(n)呢 ?
其實不是的,因為大o符號表示法並不是用於來真實代表演算法的執行時間的,它是用來表示**執行時間的增長變化趨勢的。
上面的演算法並沒有隨著某個變數的增長而增長,那麼無論這類**有多長,即使有幾萬幾十萬行,都可以用o(1)來表示它的時間複雜度。
線性階o(n)
for(i=1; i<=n; i++)
看這段**會執行多少次呢?
第1行會執行1次,第2行和第3行會分別執行n次,總的執行時間也就是 2n + 1 次,那它的時間複雜度表示是 o(2n + 1) 嗎? no !
還是那句話:「大o符號表示法並不是用於來真實代表演算法的執行時間的,它是用來表示**執行時間的增長變化趨勢的」。
所以它的時間複雜度其實是o(n);
對數階o(logn)
int i = 1;
while(i < n)
可以看到每次迴圈的時候 i 都會乘2,那麼總共迴圈的次數就是log2n,因此這個**的時間複雜度為o(logn)。
這兒有個問題,為什麼明明應該是o(log2n),卻要寫成o(logn)呢?
其實這裡的底數對於研究程式執行效率不重要,寫**時要考慮的是資料規模n對程式執行效率的影響,常數部分則忽略,同樣的,如果不同時間複雜度的倍數關係為常數,那也可以近似認為兩者為同一量級的時間複雜度。
線性對數階o(nlogn)
for(m = 1; m < n; m++)
}線性對數階o(nlogn) 其實非常容易理解,將時間複雜度為o(logn)的**迴圈n遍的話,那麼它的時間複雜度就是 n * o(logn),也就是了o(nlogn)。
平方階o(n²)
for(x=1; i <= n; x++)
}把 o(n) 的**再巢狀迴圈一遍,它的時間複雜度就是 o(n²) 了。
立方階o(n³)、k次方階o(n^k)
參考上面的o(n²) 去理解就好了,o(n³)相當於三層n迴圈,其它的類似。
三、空間複雜度計算
空間複雜度 o(1)
如果演算法執行所需要的臨時空間不隨著某個變數n的大小而變化,即此演算法空間複雜度為乙個常量,可表示為 o(1)。
int i = 1;
int j = 2;
++i;
j++;
int m = i + j;
**中的 i、j、m 所分配的空間都不隨著處理資料量變化,因此它的空間複雜度 s(n) = o(1)。
空間複雜度 o(n)
int m = new int[n]
for(i=1; i <= n; ++i)
這段**中,第一行new了乙個陣列出來,這個資料占用的大小為n,後面雖然有迴圈,但沒有再分配新的空間,因此,這段**的空間複雜度主要看第一行即可,即 s(n) = o(n)。
總結評價乙個演算法的效率主要是看它的時間複雜度和空間複雜度情況。可能有的開發者接觸時間複雜度和空間複雜度的優化不太多(尤其是客戶端),但在服務端的應用是比較廣泛的,在巨大併發量的情況下,小部分時間複雜度或空間複雜度上的優化都能帶來巨大的效能提公升,是非常有必要了解的。
常用排序演算法的時間複雜度
最差時間分析 平均時間複雜度 穩定度 空間複雜度
氣泡排序 o(n2) o(n2) 穩定 o(1)
快速排序 o(n2) o(nlog2n) 不穩定 o(log2n)~o(n)
選擇排序 o(n2) o(n2) 穩定 o(1)
二叉樹排序 o(n2) o(nlog2n) 不穩定 o(n)
插入排序 o(n2) o(n2) 穩定 o(1)
堆排序 o(nlog2n) o(nlog2n) 不穩定 o(1)
希爾排序 o o 不穩定 o(1)
演算法複雜度 時間複雜度和空間複雜度
1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數...
演算法複雜度 時間複雜度和空間複雜度
演算法複雜度 時間複雜度和空間複雜度 關鍵字 演算法複雜度 時間複雜度 空間複雜度 1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時 間多,哪個演算法花費的時間少就可以...
演算法複雜度 時間複雜度和空間複雜度
演算法的時間複雜度是指執行演算法所需要的計算工作量。n稱為問題的規模,當n不斷變化時,時間頻度t n 也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用t n 表示,若有某個輔助函式f n 存在乙個正...