你好,我是彤哥,一個每天爬二十六層樓還不忘讀源碼的硬核男人。
上一節,我們一起學習了表示複雜度的幾個符號,我們說,通常使用大O來表示算法的複雜度,不僅合理,而且書寫方便。
那麼,使用大O表示法評估算法的複雜度有沒有什麼套路呢?以及常見的複雜度有哪些呢?
本節,我們就來解決這兩個問題。
在正式講解套路之前,我們先回憶一下前面幾節講到的內容。
在第2節,我們學習了漸近分析法,將算法的複雜度與輸入規模掛鈎,隨著輸入規模的增大,算法執行的時間將呈現一種什麼樣的趨勢,將這個趨勢用函數表示,再去除低階項和常數項,就得到了算法的時間複雜度。
在第3節,我們分別從最壞、平均、最好三種情況來分析了算法的複雜度,得出結論,一般使用最壞情況來評估算法的複雜度。
在第4節,我們通過動態數組的插入元素及經典快速排序的時間複雜度,解釋了有的時候不能使用最壞情況來評估算法的複雜度。
在第5節,我們從讀音、數學、通俗理解三個方面分析了各種表示算法複雜度的符號,得出結論還是使用大O比較香,大O代表了算法的上界,它與前面講到的最壞情況往往是對應的。
所以,這裡所說的套路也是針對大部分情況,也就是最壞情況,對於一些個例,比如經典快排,我們雖然也是使用大O表示他們的複雜度,但是,其實是一種均攤的複雜度。
好了,讓我們看看計算算法複雜度的套路到底是什麼吧。
我將計算算法複雜度的套路歸納為以下五步:
比如,對於在數組中查找指定元素的操作:
所以,在數組中查找指定元素的時間複雜度為O(n)。
OK,使用這種方式可以很快的計算出算法的複雜度,也不需要進行額外的計算,非常快捷高效。
上面我們說了,複雜度的計算就是計算與輸入規模n的關係,所以,我們想想數學中關於n的函數就能得出常見的複雜度了,我繪製了一張表格:
與n的關係英文釋義複雜度示例常數(不相關)ConstantO(1)數組按索引查找元素對數相關LogarithmicO(logn)二分查找線性相關LinearO(n)遍歷數組的元素超線性相關SuperlinearO(nlogn)歸併排序、堆排序多項式相關PolynomialO(n^c)冒泡排序、插入排序、選擇排序指數相關ExponentialO(c^n)漢諾塔階乘相關FactorialO(n!)行列式展開n的n次方無O(n^n)不知道有沒有這種算法
在這張表中,複雜度是依次增加的,可以看到常數複雜度O(1)無疑是最好的,讓我們用一張圖來直觀感受下:
本節,我們一起學習了複雜度分析的套路以及常見的複雜度,到目前為止,我們不管是舉例還是講解基本上都在說時間複雜度。
那麼,空間複雜度又是什麼呢?空間與時間之間如何權衡呢?
下一節,我們接著聊。
關注公號主「彤哥讀源碼」,解鎖更多源碼、基礎、架構知識!