本篇文章收錄於專輯:http://dwz.win/HjK,點擊解鎖更多數據結構與算法的知識。算法
你好,我是彤哥,一個天天爬二十六層樓還不忘讀源碼的硬核男人。數組
上一節,咱們一塊兒學習了表示複雜度的幾個符號,咱們說,一般使用大O來表示算法的複雜度,不只合理,並且書寫方便。數據結構
那麼,使用大O表示法評估算法的複雜度有沒有什麼套路呢?以及常見的複雜度有哪些呢?架構
本節,咱們就來解決這兩個問題。ide
在正式講解套路以前,咱們先回憶一下前面幾節講到的內容。函數
在第2節,咱們學習了漸近分析法,將算法的複雜度與輸入規模掛鉤,隨着輸入規模的增大,算法執行的時間將呈現一種什麼樣的趨勢,將這個趨勢用函數表示,再去除低階項和常數項,就獲得了算法的時間複雜度。學習
在第3節,咱們分別從最壞、平均、最好三種狀況來分析了算法的複雜度,得出結論,通常使用最壞狀況來評估算法的複雜度。blog
在第4節,咱們經過動態數組的插入元素及經典快速排序的時間複雜度,解釋了有的時候不能使用最壞狀況來評估算法的複雜度。排序
在第5節,咱們從讀音、數學、通俗理解三個方面分析了各類表示算法複雜度的符號,得出結論仍是使用大O比較香,大O表明了算法的上界,它與前面講到的最壞狀況每每是對應的。索引
因此,這裏所說的套路也是針對大部分狀況,也就是最壞狀況,對於一些個例,好比經典快排,咱們雖然也是使用大O表示他們的複雜度,可是,實際上是一種均攤的複雜度。
好了,讓咱們看看計算算法複雜度的套路究竟是什麼吧。
我將計算算法複雜度的套路概括爲如下五步:
好比,對於在數組中查找指定元素的操做:
因此,在數組中查找指定元素的時間複雜度爲O(n)。
OK,使用這種方式能夠很快的計算出算法的複雜度,也不須要進行額外的計算,很是快捷高效。
上面咱們說了,複雜度的計算就是計算與輸入規模n的關係,因此,咱們想一想數學中關於n的函數就能得出常見的複雜度了,我繪製了一張表格:
與n的關係 | 英文釋義 | 複雜度 | 示例 |
---|---|---|---|
常數(不相關) | Constant | O(1) | 數組按索引查找元素 |
對數相關 | Logarithmic | O(logn) | 二分查找 |
線性相關 | Linear | O(n) | 遍歷數組的元素 |
超線性相關 | Superlinear | O(nlogn) | 歸併排序、堆排序 |
多項式相關 | Polynomial | O(n^c) | 冒泡排序、插入排序、選擇排序 |
指數相關 | Exponential | O(c^n) | 漢諾塔 |
階乘相關 | Factorial | O(n!) | 行列式展開 |
n的n次方 | 無 | O(n^n) | 不知道有沒有這種算法 |
在這張表中,複雜度是依次增長的,能夠看到常數複雜度O(1)無疑是最好的,讓咱們用一張圖來直觀感覺下:
本節,咱們一塊兒學習了複雜度分析的套路以及常見的複雜度,到目前爲止,咱們無論是舉例仍是講解基本上都在說時間複雜度。
那麼,空間複雜度又是什麼呢?空間與時間之間如何權衡呢?
下一節,咱們接着聊。
關注公號主「彤哥讀源碼」,解鎖更多源碼、基礎、架構知識。