有人說,資料結構與演算法,計算機網路,與作業系統都一樣,脫離日常開發,除了面試這輩子可能都用不到呀!
有人說,我是做業務開發的,只要熟練api,熟練框架,熟練各種中介軟體,寫的**不也能「飛」起來嗎?
於是問題來了:為什麼還要學習資料結構與演算法呢?
#理由一:面試的時候,千萬不要被資料結構與演算法拖了後腿
#理由二:
你真的願意做一輩子crud boy嗎
#理由三:
不想寫出開源框架,中介軟體的工程師,不是好廚子
我想好了,還是需要學習資料結構與演算法。但是我有兩個困惑:
1.如何著手學習呢?
2.有哪些內容要學習呢?
學習方法推薦:
#學習方法1.從基礎開始,系統化學習
2.多動手,每一種資料結構與演算法,都自己用**實現出來
3.思路更重要:理解實現思想,不要背**
4.與日常開發結合,對應應用場景
學習內容推薦:
資料結構與演算法內容比較多,我們本著實用原則,學習經典的、常用的資料結構、與常用演算法
#學習內容:1.資料結構的定義
2.演算法的定義
3.複雜度分析
4.常用資料結構
陣列、鍊錶、棧、佇列
雜湊表、二叉樹、堆
跳表、圖
5.常用演算法
遞迴、排序、二分查詢
搜尋、雜湊、貪心、分治
動態規劃、字串匹配
在開篇中提到了複雜度分析,與大o表示法的概念。具體要如何進行複雜度分析,以及大o表示法的公式推導,我們在這一篇詳細來看。
#考考你:1.你知道大o表示法,公式是如何來的嗎?
2.你知道時間複雜度分析的常用原則嗎?
3.你知道常見複雜度的度量級嗎?
3.1.1.案例**
我們根據以下案例**推導大o表示法的公式。**很簡單,有沒有?
//傳入引數n,求解1..n的累加和
public int
sum(int
n)
return
sum;
}
3.1.2.推導過程
簡述:1.對於程式**中的每一行**,從cpu的角度來看,執行的時候都有:讀資料->運算->寫資料過程
3.那麼sum方法中,**執行的總時間是多少呢
1 public intsum(int
n)
6 return sum;//
第五行、第六行**暫時忽略,不影響
7 }
4.根據3推導,sum方法的總執行時間是:
t(n)=(n + n + 1) * unit_time = (2n +1) * unit_time=o(f(n))
5.結論:所有**的執行時間t(n),與每行**的執行次數成正比
6.提取出公式即:t(n) = o(f(n))
#公式解讀:t(n):代表**執行時間
n:代表資料規模
f(n):代表每行**執行的次數總和
o:表示**執行時間t(n),與**執行次數f(n)成正比
7.這就是大o表示法的公式**,表示**的執行時間t(n),與**的執行次數f(n)成正比
8.進一步理解:
1.大o表示法:時間複雜度,表示資料規模n的增長,與演算法執行時間的增長趨勢
2.大o表示法:空間複雜度,表示資料規模n的增長,與演算法儲存空間的增長趨勢
3.1.3.約定
大o表示的公式,以及含義我們已經推導出來了。它表示的是資料規模n的增長,與演算法執行時間,或者儲存空間的增長趨勢。這裡需要關注兩個字:趨勢。
根據常理我們知道,常量、係數、低階不會影響趨勢,因此在實際複雜度分析中,往往忽略常量、係數、低階。
那麼上面案例的時間複雜度大o表示法公式,省略係數、常量:
可以從:t(n) = o(f(n)) = o(2n+1)
簡化成:t(n) = o(n)
在複雜度分析中,有時間複雜度分析和空間複雜度分析。它們是從兩個維度來衡量演算法的優劣。實際分析方式類似,我們以時間複雜度分析為例。
時間複雜度分析,有幾個基本的原則,你都知道嗎?
#時間複雜度分析基本原則1.只關注迴圈次數最多的**
2.加法法則:總複雜度等於量級最大的那段**的複雜度
3.乘法法則:巢狀**的複雜度等於巢狀內外**複雜度的乘積
3.2.1.只關注迴圈次數最多的**
案例**:
1 public intsum(int
n)
6 return sum;//
第五行、第六行**暫時忽略,不影響
7 }
複雜度分析:
1.這裡的原則:只關注迴圈次數最多的**
2.第二行**執行,需要1 個unit_time
3.第三行**執行,需要n 個unit_time
4.第四行**執行,需要n 個unit_time
5.第五行、第六行**暫時忽略,不影響
6.通過以上分析,第三行、第四行**迴圈執行次數最多:n。因此時間複雜度為:o(n)
3.2.2.加法法則
簡述:加法法則:總複雜度等於量級最大的那段**的複雜度
案例**:
public intsum(int
n)
//第二段**
int sum_2 = 0
;
for(int j = 1; j <= n; j++)
//第三段**
int sum_3 = 0
;
for(int k = 1; k <= n;k++)
}return sum_1 + sum_2 +sum_3;
}
複雜度分析:
1.在sum方法中有兩段**
2.第一段**,複雜度是:o(100)
3.第二段**,複雜度是:o(n)
4.第三段**,複雜度是:o(n^2)
5.總複雜度是:o(100) + o(n) +o(n^2)
6.根據加法法則,最終複雜度是:o(n^2)
3.2.3.乘法法則
簡述:乘法法則:巢狀**的複雜度等於巢狀內外**複雜度的乘積
案例**:
public intsum(intn)}
public
int multi(int
n)
return multi_1;
}
複雜度分析:
1.在sum方法中,有第一層迴圈:for(int i=1; i< n; i++){
2.在sum方法中,呼叫multi方法
3.在multi方法中,有第二層迴圈:for(int i = 1; i<= n; i++){
4.根據乘法法則,總時間複雜度等於,第一層迴圈,乘以第二層迴圈
5.因此總時間複雜度是:o(n*n) = o(n^2)
#考考你答案:1.你知道大o表示法,公式是如何來的嗎?
1.1.參考【3.1
.大o表示法公式推導】 2
.你知道時間複雜度分析的常用原則嗎?
2.1.只關注迴圈次數最多的**
2.2.加法法則:總複雜度等於量級最大的那段**的複雜度
2.3.乘法法則:巢狀**的複雜度等於巢狀內外**複雜度的乘積 3
.你知道常見複雜度的度量級嗎?
3.1.常數階:o(1)
2.2.對數階:o(logn)
2.3.線性階:o(n)
2.4.線性對數階:o(nlogn)
2.5.平方階:o(n^2)
2.6.立方階:o(n^3)
資料結構與演算法系列2 複雜度分析(上)
1.資料結構和演算法解決是 如何讓計算機更快時間 更省空間的解決問題 2.因此需從執行時間和占用空間兩個維度來評估資料結構和演算法的效能。3.分別用時間複雜度和空間複雜度兩個概念來描述效能問題,二者統稱為複雜度。4.複雜度描述的是演算法執行時間 或占用空間 與資料規模的增長關係。1.和效能測試相比,...
資料結構與演算法系列 時間 空間複雜度
資料結構和演算法本質就是幫我們用最快的時間和最少的空間來執行我們的 所以,執行效率是衡量乙個演算法的非常重要的指標。那如何來計算你的演算法 的執行效率呢?這就需要時間 空間複雜度來分析了。有人可能會說,我把 執行一遍,然後通過統計 監控就能知道執行的時間和需要的記憶體大小。幹嘛還需要時間 空間複雜度...
資料結構與演算法系列課程之二 複雜度分析(下)
例項 全域性變數,大小為10的陣列 array,長度 len,下標 i。int array new int 10 int len 10 int i 0 往陣列中新增乙個元素 void add int element new array複製給 array,array現在大小就是2倍 len array...