[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)