翻譯:瘋狂的技術宅原文:https://www.freecodecamp.org/...javascript
未經容許嚴禁轉載前端
在計算機科學中,算法分析是很是關鍵的部分。找到解決問題的最有效算法很是重要。可能會有許多算法可以解決問題,但這裏的挑戰是選擇最有效的算法。如今關鍵是假如咱們有一套不一樣的算法,應該如何識別最有效的算法呢?在這裏算法的空間和時間複雜度的概念出現了。空間和時間複雜度是算法的測量尺度。咱們根據它們的空間(內存量)和時間複雜度(操做次數)來對算法進行比較。java
算法在執行時使用的計算機內存總量是該算法的空間複雜度(爲了使本文更簡短一些咱們不會討論空間複雜度)。所以,時間複雜度是算法爲完成其任務而執行的操做次數(考慮到每一個操做花費相同的時間)。在時間複雜度方面,以較少的操做次數執行任務的算法被認爲是有效的算法。可是空間和時間複雜性也受操做系統、硬件等因素的影響,不過如今不考慮它們。
git
咱們將經過解決一個特定問題的例子來幫你理解時間複雜度,程序員
這個問題是搜索。咱們必須在數組中查找一個元素(在這個問題中,假設數組已經按升序排序)。爲了解決這個問題,咱們有兩種算法:面試
假設數組包含十個元素,要求咱們在數組中找到數字 10。算法
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const search_digit = 10;
線性搜索算法會將數組的每一個元素與 search_digit 進行比較,當它在數組中找到 search_digit 時,會返回 true。如今讓咱們計算它執行的操做次數。這裏的答案是10(由於它比較了數組的每一個元素)。所以線性搜索使用十個操做來查找給定元素(這是使用線性搜索算法時對此數組的最大操做數,這也被稱爲最壞狀況。一般線性搜索在最壞的狀況下會進行 n 次操做(其中 n 是數組的大小)。segmentfault
讓咱們來看看一樣狀況下的二分搜索算法。數組
經過此圖能夠輕鬆理解二分搜索:服務器
若是要在這個問題上應用此邏輯,那麼首先咱們將 search_digit 與數組的中間元素進行比較,即 5。如今,由於 5 小於 10,那麼咱們將開始在大於 5 的數組元素中尋找 search_digit ,不斷執行相同的操做直到咱們找到所需的元素 10 爲止。
如今試着計算使用二分搜索找到所需的元素進行的操做次數:大約須要四次操做。這是二分搜索的最壞狀況。這代表,執行的操做數和數組的總大小之間存在對數關係。
操做次數 = log(10) = 4(約)
咱們能夠將此結果推廣到二分搜索:
對於大小爲 n 的數組,二分搜索執行的操做數爲:log(n)
在上面的陳述中,咱們看到對於大小爲 n 的數組,線性搜索將執行 n 次操做來完成查找,而二分搜索執行 log(n) 次操做(二者都是最糟糕的狀況)。咱們能夠將其表示爲圖形(x軸:元素數量,y軸:操做次數)。
從圖中能夠清楚地看出,線性搜索時間複雜度的增加速度比二分搜索快得多。
當咱們分析算法時,通常使用 Big O 表示法來表示其時間複雜度。
例如:線性搜索的時間複雜度能夠表示爲 O(n) ,二分搜索表示爲 O(log n),其中,n 和 log(n) 是執行的操做次數。
下面列出了一些流行算法的時間複雜度或大O符號:
若是你讀到了這裏,我很是感謝。如今,必需要理解時間複雜性爲什麼如此重要?咱們知道,對於少許元素來講(好比說10),二元搜索和線性搜索所執行的操做次數之間的差別並不大,但在現實世界中的大多數時候,咱們處理的是大塊數據的問題。加入咱們有40億個元素要搜索,那麼在最壞的狀況下,線性搜索將須要40億次操做才能完成任務,而二分搜索只須要32次操做就能完成。它們之間的區別是很是巨大的。假設若是一個操做須要1毫秒才能完成,那麼二進制搜索將只須要32毫秒,而線性搜索將花費40億毫秒,也就是大約46天。這是一個顯著的差別。這就是爲何在涉及如此大的數據量時,研究時間複雜性是很是重要的緣由。