使用Swift學習數據結構和算法

stract.png

  • 主要分享最近學習的數據結構和排序算法
  • 文章只涉及每一種數據結構經過代碼實現的函數定義
  • 涉及的每一種數據結構或者算法基本都經過代碼實現了
  • GitHub代碼地址: 數據結構和算法

線性表

linear_list.png

鏈表

  • 鏈表是一種鏈式存儲的線性結構, 全部元素的內存地址不必定是連續的
  • 下表是爲四種鏈表和測試項目中對應的類名
class List<E: Comparable> {
    /** * 清除全部元素 */
    func clear() {}

    /** * 元素的數量 * @return */
    func size() -> Int { }

    /** * 是否爲空 * @return */
    func isEmpty() -> Bool { }

    /** * 是否包含某個元素 * @param element * @return */
    func contains(_ element: E) -> Bool { }

    /** * 添加元素到尾部 * @param element */
    func add(_ element: E) {}

    /** * 獲取index位置的元素 * @param index * @return */
    func get(_ index: Int) -> E? { }

    /** * 替換index位置的元素 * @param index * @param element * @return 原來的元素ֵ */
    func set(by index: Int, element: E) -> E? { }

    /** * 在index位置插入一個元素 * @param index * @param element */
    func add(by index: Int, element: E) {}

    /** * 刪除index位置的元素 * @param index * @return */
    func remove(_ index: Int) -> E? { }

    /** * 查看元素的索引 * @param element * @return */
    func indexOf(_ element: E) -> Int { }
}
複製代碼
鏈表 類名
單向鏈表 SingleLinkList
雙向鏈表 DoubleLinkList
單向循環鏈表 CircleSingleLineList
雙向循環鏈表 CircleDoubleLinkList

  • 棧是一種特殊的線性表, 只能在一端進行操做
  • 棧遵循後進先出的原則, Last in First out
  • Statck
class Statck<E> {
    /// 元素個數
    func size() -> Int {}
    
    /// 是否爲空
    func isEmpty() -> Bool { }
    
    /// 入棧
    func push(_ element: E?) {}
    
    /// 出棧
    @discardableResult
    func pop() -> E? {}
    
    /// 獲取棧頂元素
    func peek() -> E? {}
    
    /// 清空
    func clear() {}
}
複製代碼

隊列

  • 隊列是一種特殊的線性表, 只能在頭尾兩端進行操做
  • 隊列遵循後進先出的原則(單端隊列), First in First out
  • 下表是爲隊列和測試項目中對應的類名
class Queue<E: Comparable> {
    /// 元素數量
    func size() -> Int {}
    
    /// 是否爲空
    func isEmpty() -> Bool {}
    
    /// 清除全部元素
    func clear() {}
    
    /// 入隊
    func enQueue(_ element: E?) {}
    
    /// 出隊
    func deQueue() -> E? {}
    
    /// 獲取隊列的頭元素
    func front() -> E? {}
    
    func string() -> String {}
}
複製代碼
隊列 類名
單端隊列 SingleQueue
雙端隊列 SingleDeque
單端循環隊列 CircleQueue
雙端循環隊列 CircleDeque

哈希表

  • 哈希表也稱之爲散列表, 童年各國數組存儲(非單純的數組)
  • 利用哈希函數生成key對應的index值爲數組索引存儲value值
  • 兩個不一樣的key值經過哈希函數可能獲得相同的索引, 即哈希衝突
  • 解決哈希衝突的常見方法
    • 開放定址法: 按照必定規則向其餘地址探測, 知道遇到空桶
    • 再哈希法: 設計多個複雜的哈希函數
    • 鏈地址法: 經過鏈表將同一index索引的與元素串起來, 測試項目中使用的這種方式
class Map<K: Hashable, V: Comparable> {
    /// 元素數量
    func count() -> Int {}
    
    /// 是否爲空
    func isEmpty() -> Bool {}
    
    /// 清除全部元素
    func clear() {}
    
    /// 添加元素
    @discardableResult
    func put(key: K?, val: V?) -> V? {}
    
    /// 刪除元素
    @discardableResult
    func remove(key: K) -> V? {}
    
    /// 根據元素查詢value
    func get(key: K) -> V? {}

    /// 是否包含Key
    func containsKey(key: K) -> Bool {}
    
    /// 是否包含Value
    func containsValue(val: V) -> Bool {}

    /// 全部key
    func keys() -> [K] {}

    /// 全部value
    func values() -> [V] {}

    /// 遍歷
    func traversal(visitor: ((K?, V?) -> ())) {}
}
複製代碼

二叉樹

  • 二叉樹是n(n>=0)個結點的有限集合,該集合或者爲空集(稱爲空二叉樹),或者由一個根結點和兩棵互不相交的、分別稱爲根結點的左子樹和右子樹組成
二叉樹 類名
二叉樹 BinaryTree
二叉搜索樹 BinarySearchTree

AVL樹和紅黑樹是兩種平衡二叉搜索樹git

平衡二叉搜索樹 類名
二叉平衡樹 BinaryBalanceTree
二叉平衡搜索樹 BinaryBalanceSearchTree
紅黑樹 RedBlackTree

集合

測試項目中分別用鏈表, 紅黑樹, 哈希表實現了三種集合github

class Set<E: Comparable & Hashable> {
    /// 元素個數
    func size() -> Int {}
    
    /// 是否爲空
    func isEmpty() -> Bool {}
    
    /// 清除全部元素
    func clear() {}
    
    /// 是否包含某元素
    func contains(_ val: E) -> Bool {}
    
    /// 添加元素
    func add(val: E) {}
    
    /// 刪除元素
    @discardableResult
    func remove(val: E) -> E? {}
    
    /// 獲取全部元素
    func lists() -> [E] {}
}
複製代碼
集合 類名
雙向鏈表集合 ListSet
紅黑樹集合 TreeSet
哈希表集合 HashSet

二叉堆

堆是一種樹狀的數據結構, 二叉堆只是其中一種, 除此以外還有算法

  • 多叉堆
  • 索引堆
  • 二項堆
  • ....

測試項目中是以二叉堆實現了最大堆和最小堆swift

class AbstractHeap<E: Comparable> {
    /// 元素的數量
    func count() -> Int {}
    
    /// 是否爲空
    func isEmpty() -> Bool {}
    
    /// 清空
    func clear() { }
    
    /// 添加元素
    func add(val: E) { }
    
    /// 添加元素數組
    func addAll(vals: [E]) { }
    
    /// 得到堆頂元素
    func top() -> E? {}
    
    /// 刪除堆頂元素
    func remove() -> E? {}
    
    /// 刪除堆頂元素的同時插入一個新元素
    func replace(val: E) -> E? {}
}
複製代碼
二叉堆 類名
二叉堆 BinaryHeap
最大堆 MinHeap
最小堆 MaxHeap

並查集

  • 並查集也叫不相交集合, 有查找和合並兩個核心操做
  • 查找: 查找元素所在的集
  • 合併: 將兩個元素所在的集合併爲一個集
class UnionFind {
    /// 查找V所屬的集合(根節點)
    func find(v: Int) -> Int {}
    
    /// 合併v1, v2所在的集合
    func union(v1: Int, v2: Int) { }
    
    /// 檢查v1, v2是否屬於同一個集合
    func isSame(v1: Int, v2: Int) -> Bool {}
}
複製代碼
並查集 類名
Quick Find UnionFind_QF
Quick Union UnionFind_QU
QU基於size優化 UnionFind_QU_Size
QU基於size優化 UnionFind_QU_Size
QU基於rank優化 UnionFind_QU_Rank
QU基於rank的優化, 路徑壓縮 UnionFind_QU_Rank_PC
QU基於rank的優化, 路徑分裂 UnionFind_QU_Rank_PS
QU基於rank的優化, 路徑減半 UnionFind_QU_Rank_PH
泛型並查集 GenericUnionFind

  • 圖由頂點和邊組成, 分有向圖和無向圖 ---> ListGraph
  • ListGraph繼承自Graph
class Graph<V: Comparable & Hashable, E: Comparable & Hashable> {
    
    /// 邊的個數
    func edgesSize() -> Int {}
    
    /// 頂點個數
    func verticesSize() -> Int {}
    
    /// 添加頂點
    func addVertex(val: V) {}
    
    /// 添加邊
    func addEdge(from: V, to: V) {}
    
    /// 添加邊(帶權重)
    func addEdge(from: V, to: V, weight: Double?) {}
    
    /// 刪除頂點
    func removeVertex(val: V) {}
    
    /// 刪除邊
    func removeEdge(from: V, to: V) {}
    
    /// 廣度優先搜索(Breadth First Search)
    func breadthFirstSearch(begin: V?, visitor: ((V) -> ())) {}
    
    /// 深度優先搜索(Depth First Search)[非遞歸]
    func depthFirstSearch(begin: V?, visitor: ((V) -> ())) {}
    
    /// 深度優先搜索(Depth First Search)[遞歸]
    func depthFirstSearchCircle(begin: V?, visitor: ((V) -> ())) {}
    

    /* * 拓撲排序 * AOV網的遍歷, 把AOV的全部活動排成一個序列 */
    func topologicalSort() -> [V] {}

    /* * 最小生成樹 * 最小權值生成樹, 最小支撐樹 * 全部生成樹中, 權值最小的那顆 * prim算法方式 */
    func mstPrim() -> HashSet<EdgeInfo<V, E>>? {}
    
    /* * 最小生成樹 * 最小權值生成樹, 最小支撐樹 * 全部生成樹中, 權值最小的那顆 * prim算法方式 */
    func mstKruskal() -> HashSet<EdgeInfo<V, E>>? {}
    
    /* * 有向圖 * 從某一點出發的最短路徑(權值最小) * 返回權值 */
    func shortestPath(_ begin: V) -> HashMap<V, Double>? {}
    
    /* * Dijkstra: 單源最短路徑算法,用於計算一個頂點到其餘全部頂點的最短路徑 * 不支持有負權邊 */
    func dijkstraShortPath(_ begin: V) -> HashMap<V, PathInfo<V, E>>? {}
    
    /* * bellmanFord: 單源最短路徑算法,用於計算一個頂點到其餘全部頂點的最短路徑 * 支持有負權邊 * 支持檢測是否有負權環 */
    func bellmanFordShortPath(_ begin: V) -> HashMap<V, PathInfo<V, E>>? {}
    
    /* * Floyd: 多源最短路徑算法,用於計算任意兩個頂點的最短路徑 * 支持有負權邊 */
    func floydShortPath() -> HashMap<V, HashMap<V, PathInfo<V, E>>>? {}
    
    /// 輸出字符串
    func printString() {}
}
複製代碼

排序

排序 類名
冒泡排序 BubbleSorted2
選擇排序 SelectedSorted
插入排序 InsertionSorted1
歸併排序 MergeSort
希爾排序 ShellSort
快速排序 QuickSorted
堆排序 HeapSorted
計數排序 CountingSorted
基數排序 RadixSorted
桶排序 BucketSorted
/// 快速排序
let arr = [126, 69, 593, 23, 6, 89, 54, 8]
let quick = QuickSorted<Int>()
print(quick.sorted(by: arr))

/// 桶排序
let sort = BucketSorted()
let array = [0.34, 0.47, 0.29, 0.84, 0.45, 0.38, 0.35, 0.76]
print(sort.sorted(by: array))
複製代碼

總結

  • 數據結構部分除了跳錶和串其餘的基本都實現了
  • 算法部分除了排序, 其餘都暫時尚未學習
  • 這部分的學習就暫時告一段落, 接下來我要準備11月份的考試
  • GitHub代碼地址: 數據結構和算法
相關文章
相關標籤/搜索