本篇開始,梳理總結數據結構與算法。雖然開的系列都比較多,但是都很重要。程序員
數據結構和算法是區分程序員和碼農的標誌之一,固然我認爲軟件工程師比程序員更高級一些哈。算法
系列中每篇都是消化吸取之後再整理的,以此來標識本身這部分已經理解了。 咳咳咳,咱們學習他們的目的也只是爲了應用,像是什麼數據推理證實之類的,呃,脫離場景都是耍流氓,我又不作算法方向,花這麼大經歷去研究證實過程之類的,mdzz嗎?因此之後文章都是偏應用方向。編程
不負責推薦一波,固然都是廣受好評的。只看過《算法》。數組
可能配合着看更好吧數據結構
入門:《大話數據結構》,《算法圖解》數據結構和算法
系統學習:《數據結構與算法描述》函數
大部頭:《算法(第4版)》性能
若是說數據結構和算法是編程的基礎之一的話,那麼接下來幾個概念就是數據結構與算法的通用基礎:學習
而他倆的理論基礎又是:atom
OK,一個個來。
先來看兩個函數的座標圖像,他們是:
座標圖爲:
能夠看到,黃色曲線的增加趨勢遠遠大於藍色曲線的增加趨勢。此時,n才取值30,若是那麼兩者的差別將會很是很是大。 在算法領域中,這個增加趨勢咱們就用 大O表示法
表示。 因此
就表示 縱座標y的值
隨 橫座標n
的增加趨勢,該增加趨勢就是
這個函數的圖像。 說完了,關於 y軸
具體指代什麼,稍後再說。
上文說的大O表示法,咱們能夠在
的情境下去看。 好比
,當處於 式1
的狀況下,因爲 大O表示法 表達的是 y軸數值的增加趨勢。假如 n 分別等於 1,1億,很明顯,起決定做用的是:
很明顯,是
。 因此
。說這個的意思呢,就是說盡管 式2
是一個多項式,可是在大O分析法的場景下,咱們只看對於增加趨勢影響最大的項。 證實也很好證實:增加趨勢顧名思義就是增加比例麼,也就至關因而 y / x
。 式子2除以 n之後就變成了:
,能夠進一步簡化成, 因此對於增加趨勢影響最大的就是第一項,
。
在算法領域中,總共就幾種須要掌握的函數圖像,以下圖:
在大O表示法下,他們表示的都是增加趨勢,你們能夠除以n後自行證實哪一個大哈,看圖也同樣。 結論:評價算法性能就是看 運行時間 和 存儲空間 佔用的。爲何是這兩個參數呢? 我認爲應該是這樣子的:結合馮諾依曼體系結構來看,計算機由:存儲器,計算器,控制器和輸入輸出設備組成。而輸入輸出設備和控制器無需考慮,因此就剩下存儲器和計算器了。算法在單臺機器上來講不就是要減小計算和存儲嗎?愚見。
嗯,因此就引出了 時間複雜度
和 空間複雜度
的概念。
上文的大O表示法中,y軸的座標值一直沒有具體定義。咱們假設機器執行每條指令的時間都是同樣,好比是1個時間單位,因此就至關於執行c條指令花費的時間單位就是c。 在分析算法的時間複雜度時,咱們把大O表示法的縱座標軸表示爲 程序執行花費的時間(或者說指令執行的次數),因此: 時間複雜度O(n)就表示爲:程序正確執行完畢花費時間的增加趨勢。而具體
則是看括號中的函數,也就是上文中的圖片,可知,是大於的。
和時間複雜度同樣,在計算空間複雜度時,O(n)就表示 程序正確執行完筆花費空間的增加趨勢,實際要比時間複雜度情景下簡單。
作個練習表示結束,分紅兩講吧,快寫吐了。 好比,分析下列程序的時間和空間複雜度:
void atom(int n) {
int arr[n];
int i;
for (int i = 0; i < n; i++) {
arr[i] = i;
}
}
複製代碼
時間複雜度爲:不論n多大,2,3行代碼都是1次,第5行for循環體內是n次,第6行for循環體內爲n次,因此整體爲:n + n + 1 + 1,咱們學習過,只看影響最大的,那麼就是 2n,進一步簡化成幾個基本函數,最終就是 n。因此:
時間複雜度爲:O(n)。
空間複雜度爲:i 之佔1個單位,arr 數組佔n個,因此最終:
空間複雜度爲:O(n)