[Graph] 1. 什麼是 Graph?
什麼是 Graph?
Graph 只是一堆 nodes + connections,如下面 4 個圖,都可以算是 Graph:
Graph 的使用情境
Graph 充斥在我們生活周遭,以下是一些常見的例子:
- 社交網路 (Social Network)
- 地址 / 地圖 (Location / Mapping)
- 路由演算法 (Routing algorithm)
- 階層視覺畫 (Visual Hierachy)
- 檔案系統優化 (File System Optimizations)
- 任何地方
Graph 的術語和種類
術語
Graph 的主要術語如下:
- Vertex:一節點 ( a node )
- Edge:連結 (connection)
種類
- Undirected Graph:沒有方向的 Graph
例如:Facebook 的 Friend 關係,Maria 是 Armie 的朋友,Armie 也是 Maria 的朋友,雙方都看得到彼此的動態
- Directed Graph:有方向的 Graph
例如:Instagram 的 Follow 關係,Maria 關注 Justine Bieber,Marie 看得到 Justine Bieber 的動態,但 Justine Bieber 沒有追蹤 Maria,所以看不到 Maria 的動態
- Weighted Graph:每個邊 (Vertext) 有被分配特別數字的 Graph,此數字即是所謂的權重 (Weight)
例如:地圖的距離,從台北到上海的直飛航班,距離是 1000 公里,但從台北到上海的轉機航班,距離是 2000 公里
圖的表示法
圖的表示法主要可以分為以下兩種:
- 鄰接矩陣 (Adjacency Matrix)
- 鄰接串列 (Adjacency List)
鄰接矩陣 (Adjacency Matrix)
Adjacency Matrix 即是用一個矩陣,來表示每個 Vertex 之間 Edge 的連結關係
再根據 Graph 的種類,對應到的矩陣也會有所不同:
- Undirected Graph:
undirected Graph 因為是雙向的,所以 Matrix 是對稱的,例如當 5 連到 4 時,4 也會連到 5,所以矩陣會是對稱的
- Directed Graph:
directed graph 因為 vertex 之間有單向的,所以 matrix 不會完全對稱,例如當 1 連到 2 時,2 沒有連到 1,所以矩陣就會是非對稱的
鄰接串列 (Adjacency List)
Graph 也可以用鄰接串列(Adjacency List)來表示。 其中每個索引代表一個頂點(Vertex),而對應的值是一個陣列,表示該頂點的邊(Edge)及其連接的頂點。例如:
- 在 0th index 的 Vertex 有連到 1st 和 5th Vertex,在 Adjacency List 就會是
[1, 5]
const adjacencyList = [];
adjacencyList[0] = [1, 5]
如果值為 string 的話,那我們可以改用 Hash Map 來表示,例如:
- 在 A Vertex 有連到 B 和 F,在 Adjacency List 就會是
['B', 'F']
const adjacencyList = {};
adjacencyList['A'] = ['B', 'F']
Adjacency Matrix 跟 Adjacency List 的 Big O 比較
- | V | - number of vertices
- | E | - number of edges
Operation | Adjacency List | Adjacency Matrix |
---|---|---|
Add Vertex | ✅ O(1) | ❌ O(|V^2|) |
Add Edge | ✅ O(1) | ✅ O(1) |
Remove Vertex | ✅ O(|E|) | ❌ O(|V^2|) |
Remove Edge | ❌ O(|E|) | O(1) |
Query | ❌ O(|V| + |E|) | ✅ O(1) |
Storage | O(|V| + |E|) | ❌ O(|V^2|) |
在 Adjacency Matrix 加 Vertex,需要多增加 1 row + 1 column。在 Adjacency List 加 Vertex,只要多一對 key value
但 Query 時,Adjacency Matrix 可以直接取得對應的 Vertex or Edge。Adjacency List 只能先取得 key 值,再去遍歷此 Vertex 有沒有對應的 Edge
總結來說:
Adjacency List | Adjacency Matrix |
---|---|
✅ 稀疏圖 (sparse graph) 中,佔更少空間 | ❌ 稀疏圖中,佔更多空間 |
✅ 遍歷所有的邊 (Edges) 速度更快 | ❌ 遍歷所有的變相對慢 |
❌ 查找邊 (Edges) 相對慢 | ✅ 查找邊 (Edges) 相對快 |
那我們究竟要用哪一個?
Adjacency List
Adjacency List
Adjacency List
Adjacency List
因為大部分的資料都傾向呈現一個 稀疏圖 (Sparser Graph),可以讓我們
- 佔更少的空間
- 遍歷所有的邊 (Edges) 速度更快
結論
Graph 是一堆 Vertex (nodes) + Edges (connections)
圖的主要元素有 Vertex 和 Edge,其中 Edge 有分為 Undirected Edge 和 Directed Edge
圖的表示法主要可以分為
- 鄰接矩陣 (Adjacency Matrix)
- 鄰接串列 (Adjacency List)
且通常會用 Adjacency List 來表示 Graph,效能比較好,因為大部分的資料都傾向呈現一個 稀疏圖 (Sparser Graph)