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