經過標題就知道當前文檔的學習來自哪裏,挺棒的學習資源,學習以後受益不淺。
Pascal 之父 Nicklaus Wirth 憑藉一個公式得到了圖靈獎:算法 + 數據結構 = 程序。node
用於衡量其算法:正確性、可讀性、健壯性(對不合理輸入的反應能力與處理能力)。
時間複雜度(time complexity):估算程序指令的執行次數(執行時間)
空間複雜度(space complexity):估算所需佔用的存儲空間算法
因此咱們在敲代碼的時候,須要有複雜度的考慮,不以結果而結果。好比 斐波那契數列 的算法能夠是如下三種實現:數據庫
/// 斐波那契數列 -> 遞歸
func fib_recarsive(data:Int) -> Int {
if data <= 1 {
return data
}
return fib_recarsive(data: (data-1)) + fib_recarsive(data: (data-2))
}
/// 斐波那契數列 -> 優化
func fib_optimize(data:Int) -> Int {
if data <= 1 {
return data
}
var first = 0
var second = 1
for _ in 0...(data-2) {
let sum = first + second
first = second
second = sum
}
return second
}
/// 斐波那契數列 -> 優化 (減小了一個變量的開銷)
func fib_optimize_best(data:Int) -> Int {
if data <= 1 {
return data
}
var first = 0
var second = 1
// Swift 能夠這麼玩
var data = data
repeat {
second += first
first = second - first
data -= 1
} while data > 1
return second
}
複製代碼
以上三種方式都能實現 斐波那契數列, 可是其執行效率以下所示:數組
圖中的結論是經過自定義 Instruments 實現,更多細節能夠參考:Xcode 中自定義 Instruments瀏覽器
經過圖中顯示,使用遞歸是效率最低的,在相同條件下使用了 5.48s,而另外兩種實現都不到 1s 的時間。bash
數組、一個很常規的線性數據結構。在數組中又分紅兩種,好比 OC 中有不可變數組與可變數組。這裏所談到的動態數組的實現,相似可變數組。故須要考慮這些方面的實現:數據結構
在實現動態數組的過程當中,須要考慮的是 擴/縮容 與及 添加/刪除時元素位置移動 的問題。post
與數組相似、也是線性數據結構,其優勢是節省內存空間、不像數組須要有預留內存空間。性能
相對特殊的線性結構,僅在一端(棧頂)進行操做。學習
原則:後進先出(Last In First Out、LIFO)
內部實現能夠藉助:鏈表與動態數組。
應用場景: 瀏覽器前進/後退、撤銷/後退、括號有效性判斷、逆波蘭表示法、等等。
只能在 頭尾 兩端進行操做。
原則:先進先出(First In First Out, FIFO)
內部實現能夠藉助:鏈表與動態數組。
思考:用棧實現隊列,準備兩個棧(inStack、outStack)
雙端隊列(deque = double ended queue): 能在頭尾 添加/刪除。
循環隊列: 使用動態數組方可實現,添加一個對頭指針(front)。
循環雙端隊列: 兩端能夠進行添加/刪除的循環隊列。
節點、根節點、父節點、子節點、兄弟節點與子樹、左子樹、右子樹。
節點的度(degree):子樹的個數
樹的度:全部節點度中的最大值
葉子節點(leaf):度爲 0 的節點
非葉子節點:度 > 0 的節點
層數(level):根節點在第一層,跟節點的子節點在第二層,以此類推
節點的深度(depth):從跟節點到當前節點的惟一節點總數
節點的高度(height):從當前節點到最遠葉子節點的路勁上的節點數
樹的深度:全部節點深度中的最大值
樹的高度:全部節點高度的最大值
樹的深度 = 樹的高度
有序樹
無需樹、也稱 自由樹
森林
特色:有序樹、節點的度最大爲 2(左子樹與右子樹)、即便只有一個子樹也須要區分左右子樹。
真二叉樹(Proper Binary Tree): 全部節點的度,要麼爲 0、要麼爲 2。
滿二叉樹(Full Binary Tree): 最後一層節點的度都爲 0,其它節點度都爲 2。
滿二叉樹必定是真二叉樹,一樣高度的二叉樹中,滿二叉樹的節點最多。
徹底二叉樹(Complete Binary Tree): 對節點從上至下、從左至右開始編號,其全部編號都能與滿二叉樹對應。
度爲 1 的節點只有左子樹
度爲 1 的節點,要麼有 1 個、要麼是 0 個
一樣節點數量的二叉樹、徹底二叉樹的高度最小
二叉樹的高度爲 h(h>1),節點數爲[2h-1, 2h -1]
總節點數爲 n,則:2h-1 ≤ n < 2h,h-1 ≤< h,h = floor(
) + 1
i 爲節點編號、i=1 爲根節點,若是 i>1,父節點編號爲 floor(i/2),若是 2i ≤ 它的左子節點編號爲 2i,若是 2i > n 則沒有左子節點,若是 2i+1 ≤ n 則右子節點編號爲 2i+1,2i+1 > n 則無由子節點
公式:n0 = n2 + 1
遍歷(Traversal): 把全部數據結構中的元素都訪問一遍。
線性遍歷:正序與逆序。
二叉樹遍歷:
前序(Preorder):根、左、右
中序(Inorder):左、根、右
後序(Postorder):左、右、根
層序(Levelorder):從上至下
二叉樹的惟一性:
前序 + 中序
後續 + 中序
兩個節點:
前驅節點(predecessor):中序遍歷的前一個節點
後繼節點(successor):中序遍歷的後一個節點
簡稱 BST,又名二叉查找、二叉排序樹。其特色:
一、任意一個節點的值都大於左子樹全部節點的值
二、任意一個節點的值都小於右子樹全部節點的值
故此樹的節點必需要具備 可比性 。接口設計:
一、size 與 clear
二、添加與刪除
三、包含(node 與內容)
爲了防止二叉搜索樹退化成 「鏈表」 的形式,故再來研究一個 平衡二叉搜索樹。目的是讓二叉搜索樹的高度控制到最矮,相比其它二叉樹,在修改(添加/刪除)節點以後,恢復搜索二叉樹,讓其更加平衡(Balance),故稱爲 平衡二叉搜索樹,簡稱 BBST。
經典的平衡二叉搜索樹有:AVL 樹與紅黑樹,也稱他們爲自平衡二叉樹。
一個與之對應的概念,叫平航因子(Balance Factor):某節點的左右子樹的高度差。
AV 的特色:
每一個節點的平衡因子只多是 一、0、-1
每一個節點的左右子樹高度差不超過 1
搜索、添加與刪除的時間複雜度度是 O()
理解的難點是恢復平衡:右旋轉、左旋轉、左右旋轉。
是一種平衡的多路(多叉)搜索樹、多使用於文件系統、數據庫的實現。
特色:
1 個節點能夠存儲超過 2 個元素,能夠擁有超過 2 個子節點
擁有二叉搜索樹的一些性質
平衡、每一個節點的全部子樹高度一致
比較矮
若是這個 B 數中一個節點最多能存儲 3 個元素,就是最多有 4 個子樹,那稱爲 4階B樹。
4 階 B 樹、也稱 2-3-4 樹。關於 B 樹,相對比較複雜的,主要仍是在於恢復平衡,相繼引出了 上溢、下溢 的概念。
也稱自平衡二叉搜索樹、也叫平衡二叉B樹,僅看概念就知道這是一顆有顏色的樹。
性質:
一、節點的顏色是 RED 或者 BLACK
二、根節點都是 BLACK
三、葉子節點(外部節點、空節點)都是 BLACK
四、RED 節點的子節點都是 BLACK : RED 節點的 parent 都是 BLACK, 根節點到葉子節點的全部路勁上不能有兩個連續的 RED 節點
五、從任一節點到葉子節點的全部路徑都包含相同數目的 BLACK 節點
紅黑樹依舊是在恢復平衡的處理上很複雜,與 4 階 B 樹有着千絲萬縷的關係(在研究 紅黑樹的時候、心中必定要有一點 B 數)。其過程當中須要知道的幾個概念:
parent:父節點
sibling:兄弟節點
uncle:叔父節點
grand:祖父節點
紅黑樹的實現很複雜,可是性能方面是相對較優的,應用也比較普遍。好比這些: