數據結構課程:圖論

圖基礎

  • 定義:描述事物之間的關係。
  • 包括:節點集V={V1,V2......,Vn},邊集合E={e1,e2,......,em},其中ei=(vi,vi‘)
  • G=<V,E>
  • 包括有向圖和無向圖
  • 空間複雜度一般爲:O(n+m)或O(n2)
  • 主要應用包括:鄰接矩陣,鄰接表


    圖的存儲結構: 
    1、鄰接矩陣表示法: 
    如果 第 1個點和第 3個點 相連則 matrix[0][2]=1;如果兩節點之間有一條弧,則鄰接矩陣中對應的元素爲1;否則爲0。可以看出,這種表示法非常簡單、直接。但是,在鄰接矩陣的所有n*n 個元素中,只有 m個爲非零元。如果網絡比較稀疏,這種表示法浪費大量的存儲空間,從而增加了在網絡中查找弧的時間。 


    2、鄰接表表示法: 
    鄰接表表示法將圖以鄰接表(adjacency lists)的形式存儲在計算機中。所謂圖的鄰接表,也就是圖的所有節點的鄰接表的集合;而對每個節點,它的鄰接表就是它的所有出弧。鄰接表表示法就是對圖的每個節點,用一個單向鏈表列出從該節點出發的所有弧,鏈表中每個單元對應於一條出弧。爲了記錄弧上的權,鏈表中每個單元除列出弧的另一個端點外,還可以包含弧上的權等作爲數據域。圖的整個鄰接表可以用一個指針數組表示。 

  • 舉例:

拓撲排序基礎:

  • 定義:有向無環圖(DAG)
  • 場景:任務依賴
  • 時間複雜度O(n+m),附加空間複雜度O(n)
  • 每次找入度爲0的點(入度就是沒有指向它的箭頭)
  • 維護入度
  • 過程:

  • 應用:假設你有一些任務,以及這些任務之間的任務依賴,每次任務有一個完成時間,假設可以無限並行,最少要多少時間才能完成?

leetcode例題參考

207. 課程表

現在你總共有 n 門課需要選,記爲 0 到 n-1

在選修某些課程之前需要一些先修課程。 例如,想要學習課程 0 ,你需要先完成課程 1 ,我們用一個匹配來表示他們: [0,1]

給定課程總量以及它們的先決條件,判斷是否可能完成所有課程的學習?

示例 1:

輸入: 2, [[1,0]] 
輸出: true
解釋: 總共有 2 門課程。學習課程 1 之前,你需要完成課程 0。所以這是可能的。

示例 2:

輸入: 2, [[1,0],[0,1]]
輸出: false
解釋: 總共有 2 門課程。學習課程 1 之前,你需要先完成​課程 0;並且學習課程 0 之前,你還應先完成課程 1。這是不可能的。

說明:

  1. 輸入的先決條件是由邊緣列表表示的圖形,而不是鄰接矩陣。詳情請參見圖的表示法
  2. 你可以假定輸入的先決條件中沒有重複的邊。

提示:

  1. 這個問題相當於查找一個循環是否存在於有向圖中。如果存在循環,則不存在拓撲排序,因此不可能選取所有課程進行學習。
  2. 通過 DFS 進行拓撲排序 - 一個關於Coursera的精彩視頻教程(21分鐘),介紹拓撲排序的基本概念。
  3. 拓撲排序也可以通過 BFS 完成。

class Solution:
    def canFinish(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        graph = collections.defaultdict(list)
        indegrees = collections.defaultdict(int)
        for u, v in prerequisites:
            graph[v].append(u)
            indegrees[u] += 1
        for i in range(numCourses):
            zeroDegree = False
            for j in range(numCourses):
                if indegrees[j] == 0:
                    zeroDegree = True
                    break
            if not zeroDegree: return False
            indegrees[j] = -1
            for node in graph[j]:
                indegrees[node] -= 1
        return True 

最短路基礎

  • 定義:假設E集合(邊集)是有權重的
  • 具象:V集合代表城市,E集合代表城市間高速路,權重爲高速路長度,兩點間存在若干條通路,長度最短的通路即最短路

單元最短路(Dijkstra):

  • 定義:給定起點s,求到任意點的最短路
  • 貪心:每次找最近的點
  • 維護s到每個點的距離
  • 局部最優等於全局最優
  • 時間複雜度O(n2),附加空間複雜度O(n)
  • 算法:

  • SPFA(Bellman-Ford)算法:參考

單源次短路:

  • 給定起點s,求到任意點的次短路(距離大於最短路的最短的路)
  • v的次短路:頂點u的最短路再加上u->v的邊,頂點u的次短路再加上u->v的邊
  • 在原來的代碼上加入次短路即可

任意兩點最短路(Floyed)

  • 求到任兩點間的最短路
  • 類似動態規劃:每次加入一個點
  • 維護任意兩點間的距離
  • 時間複雜度O(n3),附加空間複雜度O(n2)
  • 算法:

最小生成樹(Prim)

  • 定義:無向圖
  • 樹-> 無環(圈)
  • 破圈法,避圈法
  • 時間複雜度O(n^2)

To be continue......

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章